fork() and pipe()
Terry Franklin Byrum
byrum at cs.odu.edu
Wed Mar 8 01:42:32 AEST 1989
I am borrowing this account; see signature below.
Although the obvious solution is to refer to the relevant man pages, I will
concede that there are a few commands (especially in SYSV) for which the
novice can stare at the man pages a long time and still say, "That's nice,
but HOW DO YOU USE IT??". I would include fork() and pipe() among these.
Below, I present the nucleus of a program which uses fork() and pipe().
This program is intended to highlight fork() and pipe(), so error checking is
not rigorous, and signals and abnormal child exit()s are not considered.
For a pipe to work properly, each process should close() the end of the pipe
that it does not intend to use (the reader should close the writing end,
and vice-versa). For example, if the reader does not close the writing end,
it will never perceive EOF from the pipe, since the operating system knows
that there is one potential writer (the reading process itself) still active.
An additional word to the wise: any buffering of I/O, especially by a
writing process, will drive you crazy in interprocess communication.
The reading process cannot perceive anything until it is flushed out to the
operating system. If I/O is to a terminal device, output is line-buffered
by default, which is usually acceptable. But pipes are not terminals, so
full buffering is the default, and nothing gets to the OS or the reader
until 512 (or whatever) characters have been written; rarely acceptable.
If only low level calls (read, write) are used, there is no problem.
However, if you want high level calls (fprintf, putc, puts), it is well
either to do an fflush(stream) after every batch of output, or do a
setbuf(stream, (char *)0) at the start to render the stream fully unbuffered.
Lloyd Kremer
Brooks Financial Systems
...!xanth!brooks!lloyd
Have terminal ... will hack!
-------------------cut here----------------------------------------------
/*
* A sample program to demonstrate the basic syntax of fork() and pipe()
* commands. The parent process simply writes a string through a pipe
* to be received by a child process (octal dump)
*/
main()
{
extern void perror();
int pfd[2]; /* this will be an array of 2 pipe file descriptors */
if(pipe(pfd) == -1){ /* pfd[0] is read end; pfd[1] is write end */
perror("cannot create pipe");
return(1);
}
if(!fork()){
/* CHILD STARTS HERE (fork() returns 0) */
close(pfd[1]); /* child closes write end of pipe */
close(0); /* child closes its inherited stdin descriptor */
dup(pfd[0]); /* replace it with a dup() of read end of pipe */
close(pfd[0]); /* then close original read end of pipe */
execl("/bin/od", "od", "-c", (char *)0); /* child becomes "od -c" */
perror("/bin/od"); /* if we still exist here, something's wrong */
return(1);
}
/* PARENT CONTINUES HERE (fork() returns child's pid) */
close(pfd[0]); /* parent closes read end of pipe */
write(pfd[1], "The quick brown fox jumps over the lazy dog.", 44);
/* parent says what it has to say into write end of pipe */
close(pfd[1]); /* and closes it; child will read EOF on stdin and die */
wait((int *)0); /* parent awaits death of child; avoids zombie process */
return(0);
}
-------------------cut here----------------------------------------------
--
Inventions have long since reached their limit --
and I see no hope for further developments.
- Julius Frontinus, world famous engineer, Rome, 10 AD
| Terry Franklin (Frank) Byrum
| BROOKS Financial Systems, Inc.
___ | INET: byrum at cs.odu.edu
/__ _. __. _ _ /_ | UUCP: ...!sun!xanth!brooks!byrum
/ _/ \_(_/|_|\|_/ \ | DISCLAIMER: No one listens anyway!
More information about the Comp.unix.questions
mailing list