Ludovic Poitou
Wed, 08 Nov 2000 02:50:30 -0800
Here's the results I got with your test program on Solaris 8, OSF1, HP-UX, AIX.
Ludovic.
Results on Solaris 8:
bondi> sigtest
installing signal handler...
forking...
waiting for child 9253 to exit...
child 9253 has exited
sig_pid = 9253
sig_status = 25600
main_pid = -1
main_status = 9999
sigchld handler was called before waitpid (no status)
bondi>
Results on OSF1- V4.0 True64 - alpha
centauri> sigtest
installing signal handler...
forking...
waiting for child 26517 to exit...
child 26517 has exited
sig_pid = 26517
sig_status = 25600
main_pid = -1
main_status = 9999
sigchld handler was called before waitpid (no status)
Results on HP-UX B.11.00 E 9000/715
gorzon> sigtest
installing signal handler...
forking...
waiting for child 26769 to exit...
child 26769 has exited
sig_pid = 26769
sig_status = 25600
main_pid = -1
main_status = 9999
sigchld handler was called before waitpid (no status)
Results on AIX 3.4
aladin> sigtest
installing signal handler...
forking...
waiting for child 15236 to exit...
child 15236 has exited
sig_pid = 15236
sig_status = 25600
main_pid = -1
main_status = 9999
sigchld handler was called before waitpid (no status)
aladin>
Raphael Quinet wrote:
> Included below is a small test program that checks how the OS behaves
> when a child process exits while the parent is blocking on waitpid()
> and has a SIGCHLD handler installed (which also calls waitpid, and
> thus could steal the status if the signal handler is called before
> the first waitpid returns).
>
> Currently, I only tested this under Linux (2.2.13, 2.2.14), Solaris
> 2.6 and IRIX 6.5. Linux and IRIX give priority to waitpid(), Solaris
> gives priority to the signal handler. That's why several plug-ins did
> not work under Solaris.
>
> If you are running another UNIX-like system (*BSD, HP-UX, AIX, etc.),
> it would be nice if you could compile and run the following code and
> report what it says. The code does not depend on glib, gtk or any
> other libraries, so it should be easy to compile it on any system.
>
> -Raphael
>
> #include <signal.h>
> #include <sys/types.h>
> #include <sys/wait.h>
> #include <unistd.h>
>
> int pid;
> int sig_pid = 9999;
> int sig_status = 9999;
> int main_pid = 9999;
> int main_status = 9999;
>
> static void
> sigchld_handler (int signum)
> {
> sig_pid = waitpid (pid, &sig_status, WNOHANG);
> }
>
> int
> main (int argc, char *argv[])
> {
> int ret;
> struct sigaction sa;
> struct sigaction osa;
>
> printf ("installing signal handler...\n");
> sa.sa_handler = sigchld_handler;
> sigfillset (&sa.sa_mask);
> sa.sa_flags = SA_RESTART;
> ret = sigaction (SIGCHLD, &sa, &osa);
> if (ret < 0)
> {
> printf ("cannot set signal handler, bye!\n");
> exit (-1);
> }
>
> printf ("forking...\n");
> pid = fork ();
> if (pid == 0)
> {
> sleep (1);
> _exit (100);
> }
>
> printf ("waiting for child %d to exit...\n", pid);
> main_pid = waitpid (pid, &main_status, 0);
>
> printf ("child %d has exited\n", pid);
> printf (" sig_pid = %d\n", sig_pid);
> printf (" sig_status = %d\n", sig_status);
> printf (" main_pid = %d\n", main_pid);
> printf (" main_status = %d\n", main_status);
> if (sig_pid < 0)
> {
> if (main_pid < 0)
> printf ("no child status (fork failed?)\n");
> else
> printf ("waitpid got the status before sigchld handler was called\n");
> }
> else
> {
> if (main_pid < 0)
> printf ("sigchld handler was called before waitpid (no status)\n");
> else
> printf ("you seem to have a very interesting OS...\n");
> }
> }
--
Ludovic Poitou
Sun Microsystems Inc.
iPlanet E-Commerce Solutions - Directory Group - Grenoble - France