mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* A (dumb?) waitpid(2) question
@ 2004-12-22  0:26 usvyatsky, ilya
  2004-12-22  2:38 ` Steven Rostedt
  0 siblings, 1 reply; 3+ messages in thread
From: usvyatsky, ilya @ 2004-12-22  0:26 UTC (permalink / raw)
  To: linux-kernel

As dumb as it seems, I am seing a weird behavior on my RH3.0 box
(2.4.21-20.Elsmp kernel).

It looks like (contrary to the man page and POSIX .1) waitpid(2) does not
return upon a SIGALRM.

I am porting an old piece of Solaris userland code (stripped from all useful
functionality):

#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>

void sig_handler(int signal) 
{
    printf("Alarm!!!\n");
}

int main(int argc, char *argv[])
{
    int  child_pid = -1;
        
    child_pid = fork();
    if (child_pid < 0) {
	perror("cannot fork()");
	exit(1);
    }
    
    if (child_pid) {
	/* parent */
	int status = 0, timeout = 1;

	do {
	    printf("Parent: setting an alarm for %d seconds\n", timeout);

	    signal(SIGALRM, sig_handler);
	    alarm(timeout);

	    printf("Parent: waiting for a child %d\n", child_pid);
	    child_pid = waitpid(child_pid, &status, 0);

	    if (child_pid < 0) {
		if (errno == ECHILD) {
		    perror("Parent: waitpid");
		    exit(1);
		}
		if (errno == EINTR) {
		    printf("Parent: wait was interrupted by a signal");
		}
	    }
	} while (child_pid < 0);

	printf("Parent: child %d ", child_pid);
	
	if (WIFEXITED(status)) {
	    printf("terminated normally with status %d\n",  
                    WEXITSTATUS(status));
	}
	if (WIFSIGNALED(status)) {
	    printf("was killed by signal %d\n", WTERMSIG(status));
	}
    }
    else {
	/* child */
	int timeout = 6;
	
	printf("Child:  sleeping for %d seconds\n", timeout);
	sleep(timeout);
	printf("Child:  exiting\n");
	exit(0);
    }
    return 0;
}

Here is the original Solaris output:

Child:  sleeping for 6 seconds
Parent: setting an alarm for 1 seconds
Parent: waiting for a child 7187
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Child:  exiting
Parent: child 7187 terminated normally with status 0

And here's what Linux outputs:

Child:  sleeping for 6 seconds
Parent: setting an alarm for 1 seconds
Parent: waiting for a child 24282
Alarm!!!
Child:  exiting
Parent: child 24282 terminated normally with status 0

Is it a bug or a feature?
Any suggestions would be greatly appreciated...


Ilya Usvyatsky

	EMC²  		
where information lives

Phone:  508-249-1299



^ permalink raw reply	[flat|nested] 3+ messages in thread
* RE: A (dumb?) waitpid(2) question
@ 2004-12-22  2:52 usvyatsky, ilya
  0 siblings, 0 replies; 3+ messages in thread
From: usvyatsky, ilya @ 2004-12-22  2:52 UTC (permalink / raw)
  To: 'Steven Rostedt', usvyatsky, ilya; +Cc: LKML

Thanks a lot, I suspected something of this sort...

-----Original Message-----
From: Steven Rostedt [mailto:rostedt@goodmis.org] 
Sent: Tuesday, December 21, 2004 9:38 PM
To: usvyatsky, ilya
Cc: LKML
Subject: Re: A (dumb?) waitpid(2) question


On Tue, 2004-12-21 at 19:26 -0500, usvyatsky, ilya wrote:
> As dumb as it seems, I am seing a weird behavior on my RH3.0 box 
> (2.4.21-20.Elsmp kernel).
> 
> It looks like (contrary to the man page and POSIX .1) waitpid(2) does 
> not return upon a SIGALRM.
> 
> I am porting an old piece of Solaris userland code (stripped from all 
> useful
> functionality):

I changed your code with the following:

@@ -25,11 +25,15 @@
     if (child_pid) {
         /* parent */
         int status = 0, timeout = 1;
+       struct sigaction sa;
+       sa.sa_handler = sig_handler;
+       sa.sa_flags = SA_NOMASK;

         do {
             printf("Parent: setting an alarm for %d seconds\n", timeout);

-            signal(SIGALRM, sig_handler);
+           sigaction(SIGALRM, &sa,NULL);
+//            signal(SIGALRM, sig_handler);
             alarm(timeout);

             printf("Parent: waiting for a child %d\n", child_pid);


And got the following result:

$ ./alarmit
Child:  sleeping for 6 seconds
Parent: setting an alarm for 1 seconds
Parent: waiting for a child 25926
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Alarm!!!
Parent: wait was interrupted by a signalParent: setting an alarm for 1
seconds
Parent: waiting for a child -1
Child:  exiting
Parent: child 25926 terminated normally with status 0


> Is it a bug or a feature?

I guess it's a feature, and the default signal function must have SA_RESTART
set.

> Any suggestions would be greatly appreciated...
> 

Use sigaction instead of signal.


-- Steve


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2004-12-22  2:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-22  0:26 A (dumb?) waitpid(2) question usvyatsky, ilya
2004-12-22  2:38 ` Steven Rostedt
2004-12-22  2:52 usvyatsky, ilya

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®