Path: utzoo!attcan!uunet!mcvax!hp4nl!dutrun!duteca4!knop From: knop@duteca (P. Knoppers) Newsgroups: comp.os.minix Subject: Re: Pipes and other oddities... Message-ID: <449@duteca4.UUCP> Date: 20 Jan 89 10:53:38 GMT References: <6815@louie.udel.EDU> Reply-To: knop@duteca4.UUCP (Peter Knoppers) Organization: Delft University of Technology, Dep. of Electrotechnical engineering. Lines: 67 I think that this will be of more general interest. It applies to any version of *nix that I know of. In <6815@louie.udel.EDU> someone (I can't find the header of your article) wrote: > 1. My instructor insists that under *nix and/or MINIX, a single pipe can > flow data in both directions between processes... ie., a pipe can be opened > for both read and write. Please, someone back me up on this - I swear a > pipe is a one-way flow - opened for read-only at one end and write-only > at the other. Please flame one of us, gently. You're both right.... and wrong I'll explain. The pipe system call creates a FIFO structure that can be accessed through two file descriptors, one for write, one for read. The simplest way to set up a pipe between two processes is: 1: create pipe (with the pipe system call) 2: fork (to create the second process) After this both processes can read and write the pipe. (Your instructor is right.) When the shell sets up a pipe between to processes it arranges things such that one process can only write to the pipe and the other process can only read from it. (You are right.) Things go like this: 1: create a pipe (with the system call) 2: fork the 1st process (the one that will later exec the process that will write to the pipe) 3: fork the 2nd process (the one that will later exec the process that will read from the pipe) 4: wait for both processes to complete after which the shell will prompt the user for a new command. (The shell doesn't notice that its children perform an exec system call, the wait system call returns only when one of the children exits or gets killed.) If a process, or a pipe of processes is started in the background (with &) the only difference is that the shell does not wait for the processes to complete, but instead it will prompt the user immediately for the next command. Process 1 (which is a copy of the shell) now 1: closes file descriptor 1 (standard out) 2: dup's the write file descriptor of the pipe to file descriptor 1 3: closes it's read file descriptor of the pipe 4: exec's the command that is supposed to write in the pipe. (the exec-ed process will inherit the pipe as standard output) Process 2 (which is also a copy of the shell) now 1: closes file descriptor 0 (standard in) 2: dup's the read file descriptor of the pipe to file descriptor 0 3: closes it's write file descriptor of the pipe 4: exec's the command that is supposes to read from the pipe. (the exec-ed process will inherit the pipe as standard input) Comments: - When the shell sets up a pipe between two process it ensures that the communication path will be one-way. - When more than 2 processes must be created connected by pipes, the scheme gets slightly more complicated. I leave this as an exercise for the reader. - The shell cannot create a circularly connected set of processes. There is simply no way to specify such things on the command line. - It is possible to create a set of processes that is interconnected with pipes in any way you like. However, the shell will not do this for you. If at any time, any of a set of pipes that connects processes in a circular fashion, must contain more than (in most unix versions) 8 blocks of data, deadlock will occur. Your *nix kernel cannot detect this situation. (Why ? Another exercise for the reader...) - You will probably have to read this twice to understand it. The subject is not simple. You may have to (re-)read the documentation for the system calls pipe, dup, dup2, close, fork, exec and wait. -- Peter Knoppers - knop@duteca.UUCP