* 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 0:26 A (dumb?) waitpid(2) question usvyatsky, ilya
@ 2004-12-22 2:38 ` Steven Rostedt
0 siblings, 0 replies; 3+ messages in thread
From: Steven Rostedt @ 2004-12-22 2:38 UTC (permalink / raw)
To: usvyatsky, ilya; +Cc: LKML
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
* 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®