Hello! > >> - zombie processes when mcview or mcedit is started
Could you please describe in more details how you create zombies? I don't see any zombies with CVS mc and QNX Neutrino 6.2.0. Even if they are created, I don't like the approach used for SCO. Waiting for any process and discarding the exit status is not a good idea. If I had access to SCO, I would probably use something safer. I also wrote a test for popen and pclose (attached), and it works in the same way on Linux and QNX - waitpid() after pclose() fails. If waitpid() is used before pclose() in the signal handler, pclose() returns -1 instead of the exit status. This means that pclose() uses waitpid() internally and doesn't like if the caller gets the exit status itself. I guess that the SCO pclose was using just one waitpid() for two fork()s in popen() or something like that. That's not what I see in QNX. > Like what ? Making a wrapper function for pclose() or smth like that ? > I haven't discovered deeply why those zombie processes occure, but > I'll try to find what happens. Maybe a wrapper, although waiting for WAIT_ANY and discarding the status is risky - important events for other processes can be lost. In particular, the subshell stops itself to tell mc that it's ready. I would prefer to identify bogus processes and acknowledge them explicitly, possibly in the SIGCHLD handler. -- Regards, Pavel Roskin
#include <stdio.h> #include <sys/wait.h> #include <errno.h> #include <string.h> void sigchld_handler (int signum) { int pid, status, serrno; serrno = errno; while (1) { pid = waitpid (-1, &status, WNOHANG | WUNTRACED); if (pid < 0) { perror ("waitpid error"); break; } if (pid == 0) break; printf ("waitpid returned pid %d, status %d\n", pid, status); } errno = serrno; } int main () { int c; FILE *file; int ret; #if 0 signal (SIGCHLD, sigchld_handler); #endif file = popen ("echo 123; exit 1", "r"); while ((c = getc (file)) != EOF) { printf ("%c\n", c); } ret = pclose (file); printf ("pclose returned %d\n", ret); printf ("press enter\n"); getc (stdin); printf ("manually calling sigchld_handler\n"); sigchld_handler (0); return 0; }