f



Zombie Apocalypse.

I have a process that drains stdout and stderr pipes from a child, then does a 
waitpid and gets the okay return with status 0. But the child remains as a 
zombie. Any suggestions?

MacOSX. The parent process is a user agent running as a child of launchd as a 
child of the login window.

-- 
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
Free the Amos Yee one.
Yeah, too bad about your so-called life. Ha-ha.
0
Siri
12/1/2016 3:11:06 PM
comp.unix.programmer 10848 articles. 0 followers. kokososo56 (350) is leader. Post Follow

2 Replies
493 Views

Similar Articles

[PageSpeed] 31

In article 
<chine.bleu-A867FE.07105801122016@news.eternal-september.org>,
 Siri Cruise <chine.bleu@yahoo.com> wrote:

> I have a process that drains stdout and stderr pipes from a child, then does 
> a 
> waitpid and gets the okay return with status 0. But the child remains as a 
> zombie. Any suggestions?
> 
> MacOSX. The parent process is a user agent running as a child of launchd as a 
> child of the login window.

Can you post the code?

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
0
Barry
12/2/2016 12:53:12 AM
In article <barmar-D02E15.19524201122016@news.eternal-september.org>,
 Barry Margolin <barmar@alum.mit.edu> wrote:

> In article 
> <chine.bleu-A867FE.07105801122016@news.eternal-september.org>,
>  Siri Cruise <chine.bleu@yahoo.com> wrote:
> 
> > I have a process that drains stdout and stderr pipes from a child, then 
> > does 
> > a 
> > waitpid and gets the okay return with status 0. But the child remains as a 
> > zombie. Any suggestions?
> > 
> > MacOSX. The parent process is a user agent running as a child of launchd as 
> > a 
> > child of the login window.
> 
> Can you post the code?

Not entirely (size + propeitary).

/*input*/   char **P, *cwd;
/*output*/  char *output, *error; int ec;
{
    int pid, forkout[2] = {-1, -1}, forkerr[2] = {-1, -1};

    /* Create pipes. */
    if (pipe(forkerr)<0) {
        fprintf(stderr, "pipe failed: %s\n", strerror(errno));
        pid = -1;
    }else if (pipe(forkout)<0) {
        fprintf(stderr, "pipe failed: %s\n", strerror(errno));
        close(forkerr[0]); close(forkerr[1]);
        close(forkin[0]); close(forkin[1]);
        pid = -1;

    /* Fork. */
    }else if ((pid=fork())<0) {
        fprintf(stderr, "fork failed: %s\n", strerror(errno));
        close(forkerr[0]); close(forkerr[1]);
        close(forkin[0]); close(forkin[1]);
        close(forkout[0]); close(forkout[1]);
    }
    
    /* Child. */
    if (pid==0) {
        close(0); open("/dev/null", O_RDONLY);
        close(1);  dup(forkout[1]);
        close(forkout[0]); close(forkout[1]);
        forkout[0] = -1; forkout[1] = -1;
        close(2); dup(forkerr[1]);
        close(forkerr[0]); close(forkerr[1]);
        forkerr[0] = -1; forkerr[1] = -1;
        if (cwd) chdir(cwd);
        execv(*P, P);
        fprintf(stderr, "exec %s: %s\n", *P, strerror(errno));
        exit(1);
        
    /* Parent, */
    }else if (pid>0) {

        /* Parent side pipes. */

        int nopen = 2;
        if (close(forkout[1])<0) {
            fprintf(stderr, "fork %s: close forkout write: %s\n",
                    *P, strerror(errno));
            abort();
        }
        forkout[1] = -1;
        fcntl(forkout[0], F_SETFL, O_NONBLOCK);
        if (close(forkerr[1])<0) {
            fprintf(stderr, "fork %s: close forkerr write: %s\n",
                *P, strerror(errno));
            abort();
        }
        forkerr[1] = -1;
        fcntl(forkerr[0], F_SETFL, O_NONBLOCK);

        /* Read child stdout and stderr. */

        int N; char B[16384]; int Q = 0;
        CORD dserr = CORD_EMPTY;
        CORD dsout = CORD_EMPTY;
        fprintf(stderr, "ORANGE server pipes read\n");
        while (nopen>0) {
            int M = 0;
            if (forkout[0]<0) {
                ;
            }else if (Q>100000) {
                kill(pid, SIGTERM); close(forkout[0]); forkout[0] = -1;
                nopen --;
            }else if ((N=read(forkout[0], B, sizeof B))>0) {
                dsout = CORD_cat_char_star(dsout, B, N); M += N;
                Q += N;
            }else if (N<0 && errno==EAGAIN) {
                N = 0;
            }else if (N<=0) {
                if (N<0) fprintf(stderr, "read exec stdout %s: %s\n",
                        *P, strerror(errno));
                if (close(forkout[0])<0) {
                    fprintf(stderr, "fork %s: close forkout read: %s\n",
                            *P, strerror(errno));
                }
                forkout[0] = -1; nopen--;
                if (forkin[1]>=0 && forkerr[0]<0)
                    fcntl(forkin[1], F_SETFL, 0);
                else if (forkin[1]<0 && forkerr[0]>=0)
                    fcntl(forkerr[0], F_SETFL, 0);
            }
            if (forkerr[0]<0) {
                ;
            }else if (Q>100000) {
                kill(pid, SIGTERM); close(forkerr[0]); forkerr[0] = -1;
                nopen--;
            }else if ((N=read(forkerr[0], B, sizeof B))>0) {
                dserr = CORD_cat_char_star(dsout, B, N); M += N;
                Q += N;
            }else if (N<0 && errno==EAGAIN) {
                N = 0;
            }else if (N<=0) {
                if (N<0)
                    fprintf(stderr, "read exec stderr %s: %s\n",
                            *P, strerror(errno));
                if (close(forkerr[0])<0) {
                    fprintf(stderr, "fork %s: close forkerr read: %s\n",
                            *P, strerror(errno));
                }
                forkerr[0] = -1; nopen--;
                if (forkin[1]>=0 && forkout[0]<0)
                    fcntl(forkin[1], F_SETFL, 0);
                else if (forkin[1]<0 && forkout[0]>=0)
                    fcntl(forkout[0], F_SETFL, 0);
            }
            if (M==0 && nopen>1) sleep(1);
            fprintf(stderr, "ORANGE nopens=%d\n", nopens);
        }
        fprintf(stderr, "ORANGE server pipes done\n");
        output = CORD_to_const_char_star(dsout);
        error = CORD_to_const_char_star(dserr);

        /* Reap child status. */

        int r, s, ec;
        fprintf(stderr, "ORANGE server waitpid before\n");
        r = waitpid(pid, &s, 0);
        fprintf(stderr, "ORANGE server waitpid after %d %d %x\n",
                r, errno, s);
        if (r<0) {
            fprintf(stderr, "waitpid failed: %s\n", strerror(errno));
            ec = -256;
        }else if (WIFEXITED(s)) {
            ec = WEXITSTATUS(s);
        }else if (WIFSIGNALED(s)) {
            ec = -WTERMSIG(s);
        }else {
            fprintf(stderr, "waitpid unknown status: %04x\n", s);
            ec = -256;
        }
    }
}


ORANGE server pipes read
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=1
ORANGE server pipes done
ORANGE server waitpid before
ORANGE server waitpid after 99569 60 0
ORANGE server pipes read
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=1
ORANGE server pipes done
ORANGE server waitpid before
ORANGE server waitpid after 99570 60 0
ORANGE server pipes read
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=1
ORANGE server pipes done
ORANGE server waitpid before
ORANGE server waitpid after 99571 60 0
ORANGE server pipes read
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=2
ORANGE nopens=1
ORANGE server pipes done
ORANGE server waitpid before
ORANGE server waitpid after 99572 60 0

-- 
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
Free the Amos Yee one.
Yeah, too bad about your so-called life. Ha-ha.
0
Siri
12/2/2016 4:58:24 AM
Reply: