FreeBSD-5.1 problem identified

Mike Makonnen mtm at identd.net
Thu Aug 7 09:46:56 CEST 2003


On Wed, Aug 06, 2003 at 09:36:07PM -0500, edscott wilson garcia wrote:
> 
> OK. The code comes from xffm/libs/tubo.c and occurs after a fork. The
> TERM signal is reset for the child which goes into pause until the
> parent sends the child the signal to continue. With the sigaction(), the
> signal terminates the child and the parent is left waiting. That's why
> it gets no answer on nmblookup, nor doing a find, nor trying to
> mount/unmount nor other things, otherwise xffm seems to work ok. It can
> browse and launch programs and stuff like that since no signals are
> involved to do that.
> 
> if I undefine HAVE_SIGNAL it won't work:
> 
> void *Tubo(void)
> {
>     int i;
>     fork_struct tmpfork, *newfork = NULL;
> 
> #ifndef HAVE_SIGNAL
>     struct sigaction act;
>     sigemptyset(&act.sa_mask);
> #ifdef SA_RESTART
>     act.sa_flags = SA_RESTART;
> #else
>     act.sa_flags = 0;
> #endif
>     act.sa_handler = TuboSemaforo;
> #endif
> 
> [some code here]
> 
> #ifdef HAVE_SIGNAL
>     signal(SIGUSR1, TuboSemaforo);
> #else
>     sigaction(SIGUSR1,&act,NULL);
> #endif
> 
> 
>     tmpfork.childPID = fork();
>     if(tmpfork.childPID)
>     {				/* the parent */
> 	newfork = (fork_struct *) malloc(sizeof(fork_struct));
> 	if(!newfork)
> 	{
> 	    /* red light to child */
> 	    perror("malloc");
> #ifdef DEBUG
>  printf("The parent process is sending a red light\n"); 
> #endif
> 	    kill(tmpfork.childPID, SIGTERM);
> 	    TuboChupoFaros(NULL);
> 	    return NULL;
> 	}
> #ifdef DEBUG
>  printf("The parent process is sending a green light\n"); 
> #endif
> 	kill(newfork->childPID, SIGUSR1);
	     ^^^^^^^
	    is this a typo or you just didn't include the code
	    that set the value?


> 	return newfork;		/* back to user's program flow */
>     }
>     else
>     {				/* the child */
> 	/* waitfor green light. */
> #ifdef HAVE_SIGNAL
> 	signal(SIGTERM, TuboSemaforo);
> #else
> 	sigaction(SIGTERM,&act,NULL);
> #endif
> 	
> #ifdef DEBUG
>  printf("The child process is waiting for the green light\n"); 
> #endif
> 	pause();
> #ifdef DEBUG
>  printf("The child has received the green light\n"); 
> #endif
> 
> 
> Looking over the code, it seems that if I use sigaction, the child
> receives the signal USR1 and terminates (default for USR1). But if I use
> signal() it calls the handler and merrily goes on its way. Maybe there
> is a race condition in FreeBSD and that is why it fails on my box but
> works on yours. OTH, shouldn't signal be preferred (if available) since
> it is simple and straightforward?

On FreeBSD signal() is simply a wrapper around sigaction(). So, this
shouldn't be happening. It's entirely possible there's a bug with
signal handling in the kernel, but then it should appear regardless
of which invocation you use. I'll write up a small test-case using
the information you posted above and see if I can reproduce the
problem. We'll see where to go from there.

Cheers.
-- 
Mike Makonnen  | GPG-KEY: http://www.identd.net/~mtm/mtm.asc
mtm at identd.net | D228 1A6F C64E 120A A1C9  A3AA DAE1 E2AF DBCC 68B9
mtm at FreeBSD.Org| FreeBSD - Unleash the Daemon!



More information about the Xfce4-dev mailing list