Saving stderr output in memory

Maarten Litmaath maart at cs.vu.nl
Thu Mar 15 10:09:58 AEST 1990


In article <7406 at jpl-devvax.JPL.NASA.GOV>,
	lwall at 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	<stdio.h>

#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 at cs.vu.nl, uunet!mcsun!botter!maart



More information about the Comp.unix.wizards mailing list