Re: Problems with the undead (zombies)
Brandon Mitchell <bhmit1@mail.wm.edu> writes:
> Placing a wait someone else may cause your program to hang until a child
> dies. But note that if you have a select or some other kernel call, you
> will exit from that call with some kind of error code (it took me a while
> to realize this, never stopped using perror since then).
This depends on how you compile your code (i.e. if _BSD_SOURCE gets
defined, then the calls don't get interrupted.) You can also set it
with siginterrupt(); or just use the POSIX sigaction() function, which
is always the best way.
Of course, perror() is still a good idea.
Jason Gunthorpe <jgg@gpu.srv.ualberta.ca> writes:
> The man pages do not say that wait is signal safe, putting it in a single
> handler could nuke your program in some situations.
The libc info pages definitely show waitpid() as part of a signal
handler. It should be safe as long as you don't call it anywhere else
where the SIGCHLD could interrupt it.
Gergely Madarasz <gorgo@caesar.elte.hu> writes:
> Hmm... isn't signal(SIGCHLD,SIG_IGN) the best for this situation anyway?
It is on Linux, with libc5 and libc6.
Fun with signals: fork a process (like `sleep 60') then exec() another
program, which gets the SIGCHLD signal when your process ends. A few
programs take this quite badly.
Anyway, I think the program below is a good demo of how signals can be
safely handled. If you pass it any arguments, it passes SA_RESTART to
sigaction(). (If you feel you need to reply to this, please don't
quote the whole program.)
-----
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
static volatile int status;
static volatile pid_t pid;
static volatile int done = 0;
void sig_chld(int num)
{
int this_sts;
pid_t this_pid;
if (num != SIGCHLD) return;
while (1) {
if ((this_pid = waitpid(WAIT_ANY, &this_sts, WNOHANG)) > 0) {
if (this_pid == pid) {
status = this_sts;
done = 1;
}
}
else break;
}
}
int main(int argc, char **argv)
{
ssize_t n;
char buf[1024];
struct sigaction sa;
pid = fork();
if (pid == 0) {
sleep(3);
_exit(EXIT_SUCCESS);
} else if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
sa.sa_handler = sig_chld;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NOCLDSTOP;
if (argc > 1)
sa.sa_flags |= SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}
if ((n = read(0, buf, 1024)) == -1)
perror("read");
else
printf("read got %d bytes\n", n);
if (done)
printf("child exited with status 0x%04x\n", status);
return 0;
}
-----
--
Carey Evans http://home.clear.net.nz/pages/c.evans/
"[UNIX] appears to have the inside track on being the replacement for
CP/M on the largest microcomputers (e.g. those based on 68000...)"
--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Reply to: