Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!hp4nl!star.cs.vu.nl!maart From: maart@cs.vu.nl (Maarten Litmaath) Newsgroups: comp.unix.wizards Subject: Re: Saving stderr output in memory Message-ID: <5981@star.cs.vu.nl> Date: 15 Mar 90 00:09:58 GMT References: <14020086@hpisod2.HP.COM> <7406@jpl-devvax.JPL.NASA.GOV> Sender: news@cs.vu.nl Reply-To: maart@cs.vu.nl (Maarten Litmaath) Organization: VU Informatika, Amsterdam, the Netherlands Lines: 104 In article <7406@jpl-devvax.JPL.NASA.GOV>, lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: )... )When prog1 dies, the child appends the collected error messages to stdout, )plus the exit status. Your program then looks for the magic lines at the )end of the ordinary stdout output. [...] "Yech! This stuff tastes like poison." Variably-sized buffered IO etc. is left as an exercise. --------------------cut here-------------------- #include #define OUT_SIZE (10 * 1024) #define ERR_SIZE 1024 char *Prog[] = { "/bin/cat", "/etc/passwd", "/non-existent", 0 }; main() { int pp_out[2], pp_err[2], pp[2], n_out, n_err, n, pid1, pid2, w; int status; /* allright, so it should be a union wait */ char out[OUT_SIZE], err[ERR_SIZE], *p; if (pipe(pp_out) < 0 || pipe(pp_err) < 0) panic("pipe"); switch (pid1 = fork()) { case -1: panic("fork"); case 0: dup2(pp_out[1], 1); close(pp_out[1]); close(pp_out[0]); dup2(pp_err[1], 2); close(pp_err[1]); close(pp_err[0]); execv(*Prog, Prog); panic(*Prog); } close(pp_out[1]); close(pp_err[1]); if (pipe(pp) < 0) panic("pipe"); switch (pid2 = fork()) { case -1: panic("fork"); case 0: for (p = err; p < err + sizeof err; p += n) if ((n = read(pp_err[0], p, (err + sizeof err) - p)) <= 0) break; if (p > err && write(pp[1], err, p - err) < 0) panic("write"); if (n < 0) panic("read"); exit(0); } close(pp_err[0]); close(pp[1]); for (p = out; p < out + sizeof out; p += n) if ((n = read(pp_out[0], p, (out + sizeof out) - p)) <= 0) break; if (n < 0) panic("read"); n_out = p - out; for (p = err; p < err + sizeof err; p += n) if ((n = read(pp[0], p, (err + sizeof err) - p)) <= 0) break; if (n < 0) panic("read"); n_err = p - err; close(pp_out[0]); close(pp[0]); for (n = 0; n < 2; ) { w = wait(&status); if (w == pid1 || w == pid2) { if (w == pid1) printf("status: %d\n\n", status >> 8); ++n; } } printf("out:\n%s\nerr:\n%s", out, err); } panic(message) char *message; { perror(message); exit(1); } --------------------cut here-------------------- -- 1) Will 4.5BSD have wait5()? |Maarten Litmaath @ VU Amsterdam: 2) Sleep(3) should be sleep(2) again.|maart@cs.vu.nl, uunet!mcsun!botter!maart