Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Apr 2005 12:20:39 +0300
From:      Kostik Belousov <konstantin.belousov@zoral.com.ua>
To:        freebsd-hackers@freebsd.org
Subject:   sigprocmask and fork
Message-ID:  <20050418092038.GB984@deviant.zoral.local>

next in thread | raw e-mail | index | archive | help

--yrj/dFKFPuw6o+aM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,                                                                             
                                                                                
I come across the following problem:                                            
after fork(), the 5-STABLE system sets the child process                        
blocked signal mask to 0 (let us account single-threaded processes only).       
I was under impression that signal mask                                         
shall be inherited by the child process (according to SUSv3 and                 
man fork). Inheritance _was_ the behaviour of 4-STABLE (there, p_sigmask        belongs to struct proc and placed in the copied-on-fork part                    
of the structure) and also seen on other UNIXes (e.g. Solaris).

After googling, I found the comment by Dong Xuezhang in
http://lists.freebsd.org/pipermail/freebsd-threads/2005-February/002899.html    
where he said that "Actually fork() do not copy the properties of signal mask". 
                                                                                
I confirm that fork does not copy mask, but why ? Attached is the program that  
illustrates this issue on                                                       
pooma% uname -a                                              ~/work/bsd/sigmask 
FreeBSD pooma.home 5.4-STABLE FreeBSD 5.4-STABLE #32: Fri Apr 15 22:16:43 EEST 2005     root@pooma.home:/usr/obj/usr/src/sys/POOMA  i386
On unpatched 5-STABLE, the child process reports SIGUSR2 immediately after
start, despite parent blocked SIGUSR2 before forking.

It seems that needs of thread_schedule_upcall() to zero sigmask interfere
with the needs of the fork1().
I propose the trivial patch (against 5-STABLE) to fix the problems. It handles
td_sigmask in the way similar to td_sigstk, that is also zeroed on _upcall(),
as was done by davidxu at kern/kern_fork.c:1.209 rev.


Index: kern/kern_fork.c
===================================================================
RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.234.2.8
diff -U5 -r1.234.2.8 kern_fork.c
--- kern/kern_fork.c    27 Feb 2005 02:36:39 -0000      1.234.2.8
+++ kern/kern_fork.c    18 Apr 2005 08:58:50 -0000
@@ -470,10 +470,11 @@
            __rangeof(struct thread, td_startcopy, td_endcopy));
        bcopy(&td->td_ksegrp->kg_startcopy, &kg2->kg_startcopy,
            __rangeof(struct ksegrp, kg_startcopy, kg_endcopy));

        td2->td_sigstk = td->td_sigstk;
+       td2->td_sigmask = td->td_sigmask;

        /*
         * Duplicate sub-structures as needed.
         * Increase reference counts on shared objects.
         */


Thanks for attention,                                                           
Kostik Belousov.



--yrj/dFKFPuw6o+aM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sigmask1.cc"

#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <stdio.h>

extern "C" void
sigusr2_handler(int signo)
{
	static const char msg[] = "SIGUSR2\n";
	write(2, msg, sizeof(msg) - 1);
	_exit(0);
}

int
main(int argc, char *argv[])
{
	struct sigaction sa;
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sigusr2_handler;
	sigaction(SIGUSR2, &sa, NULL);

	sigset_t mask;
	sigemptyset(&mask);
	sigaddset(&mask, SIGUSR2);
	sigprocmask(SIG_BLOCK, &mask, NULL);

	pid_t child = fork();
	if (child == 0)
	{
		raise(SIGUSR2);
		printf("sleeping\n");
		sleep(10);
		printf("enabling SIGUSR2\n");
		sigprocmask(SIG_UNBLOCK, &mask, NULL);
		while (true)
			;
	}

	int status;
	wait(&status);
	return 0;
}

--yrj/dFKFPuw6o+aM--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050418092038.GB984>