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>