emmonsl@athena.ecs.csus.edu (L. Scott Emmons) (03/04/91)
I thought that perhaps some people would be interested in just how to use fork(), exec(), and pipe() to do the same thing as is possible with a system(). I cooked up a couple of quick programs. The first implements redirection using fork(), exec(), and pipe(). The second does the exact same things, except uses system() instead. NOTE: I implemented these on a BSD system...It can probably be ported over to sysV reasonably easily...change SIGCHLD to SIGCLD, and that should be about it... Just for kicks, I compared the output from 'time' for both versions of the program. Here are some average results: using fork/exec/pipe: 0.0u 0.1s 0:00 35% 5+6k 0+0io 0pf+0w using system: 0.2u 0.4s 0:00 70% 32+18k 0+4io 0pf+0w While for this trivial usage the times aren't that much difference, a larger program surely would be... Here are the two programs, enjoy and if you have any questions, comments, etc please feel free to email me at emmons@csus.csus.edu: ---CUT HERE start pipe.c--- /* This program shows how to (or one way to) implement fork() and exec() on a pipeline, redirecting the stdout of the exec()d program into the pipeline. This code was written by L. Scott Emmons, emmons@csus.csus.edu. */ #include <stdio.h> #include <signal.h> child_changed(); int fd[2]; main() { char ch=0; pipe(fd); if (fork()) { signal(SIGCHLD,child_changed); while(read(fd[0],&ch,1)) putchar(ch); close(fd[0]); } else { dup2(fd[1],1); execl("/usr/ucb/last","last","emmonsl",(char *)0); } } child_changed() { close(fd[1]); } ---CUT HERE end pipe.c--- ---CUT HERE start system.c--- /* This program shows how to (or one way to) use system() to do what fork(), exec(), and pipe() can do... It redirects the output of a program to a file, then reads the file back in and prints it. This code was written by L. Scott Emmons, emmons@csus.csus.edu. */ #include <stdio.h> main() { FILE *fp; char ch; system("/usr/ucb/last emmonsl >filename"); fp=fopen("filename","r"); while (fread(&ch,1,1,fp)) putchar(ch); fclose(fp); unlink("filename"); } ---CUT HERE end system.c--- L. Scott Emmons --------------- emmons@csus.csus.edu <or> ...[ucbvax]!ucdavis!csus!emmons Packet: kc6nfp@kg6xx.#nocal.ca.usa.na
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/06/91)
In article <1991Mar3.214844.15444@csusac.csus.edu> emmonsl@athena.ecs.csus.edu (L. Scott Emmons) writes: > using fork/exec/pipe: 0.0u 0.1s 0:00 35% 5+6k 0+0io 0pf+0w > using system: 0.2u 0.4s 0:00 70% 32+18k 0+4io 0pf+0w This is, of course, because you aren't waiting for the child to finish. ---Dan
emmonsl@athena.ecs.csus.edu (L. Scott Emmons) (03/08/91)
In article <5866:Mar604:22:3791@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >This is, of course, because you aren't waiting for the child to finish. Actually, it does finish...the child closes the pipeline down when it is done. The read() reads unless eof, which it only returns when the write end of the pipeline is closed (it blocks if the pipeline is open with no data in it). I just did it all implicitly...If anyone can come up with an example where this wouldn't work please let me know. (except the obvious, where the child doesn't close the pipe, of course...but then, you are changing the environment of the usage, of course) Remember also, that I ignored all the return codes for simplicity in the examples. Check out my second version, it works the same, but is easier to see how I implemented this. L. Scott Emmons --------------- emmons@csus.csus.edu <or> ...[ucbvax]!ucdavis!csus!emmons Packet: kc6nfp@kg6xx.#nocal.ca.usa.na
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/08/91)
In article <1991Mar7.180531.7907@csusac.csus.edu> emmonsl@athena.ecs.csus.edu (L. Scott Emmons) writes: > In article <5866:Mar604:22:3791@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > >This is, of course, because you aren't waiting for the child to finish. > Actually, it does finish...the child closes the pipeline down when it is done. Irrelevant. Your parent does not call wait(), so your timings are wrong. ---Dan