Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!ames!umd5!vrdxhq!bms-at!stuart From: stuart@bms-at.UUCP (Stuart D. Gathman) Newsgroups: comp.unix.wizards Subject: Re: Shared Memory --- Parallel filters and piping -- Examples Needed Message-ID: <583@bms-at.UUCP> Date: 19 Feb 88 18:35:01 GMT References: <11876@brl-adm.ARPA> Organization: Business Management Systems, Inc., Fairfax, VA Lines: 75 > From: "John S. Robinson" > If a programmer has filters filt1, filt2, ... filtn which he wishes to > apply in a serial fashion on a stream of data, the process can be accomplished > in a trivial fashion by use of a sequence of pipes: > filt1 < |filt2 |filt3 | ... |filtn > . > How does one handle the case where some of the above filters are to be > applied in parallel and then be recombined: Here is my solution: filt1|cat `@ filt2` `@ filt3`|filt4 The '@' program executes its arguments ala 'nohup' or 'nice' with stdout connected to a named pipe. The name of the named pipe is printed on @'s standard output (which is different from the program it runs). Note that this function cannot be written as a shell script because the shell insists on waiting for all background processes before exiting. /* @.c */ #include #include static char null[] = "/dev/null"; /* null device in case of error */ main(argc, argv) char **argv; { char *fname; int fd; fname = tempnam(NULL,"@pipe"); if (argc < 2) { puts(null); return 1; } fd = mknod(fname,0010600); if (fd == -1) { perror(fname); puts(null); return 1; } switch (fork()) { case 0: close(1); fd = open(fname,O_WRONLY); if (fd != 1) return 1; switch (fd = fork()) { case 0: execvp(argv[1],argv+1); /* try to execute direct */ perror(argv[1]); return 1; case -1: perror("fork"); unlink(fname); return 1; default: while (wait((int *)0) != fd); unlink(fname); return 0; } case -1: perror("fork"); puts(null); return 1; default: puts(fname); } return 0; } -- Stuart D. Gathman <..!{vrdxhq|dgis}!bms-at!stuart>