Anonymous Pipes Overview

A typical use of an anonymous pipe is to create a channel for communication between a parent process and its child process by redirecting the standard input or standard output handles of the child process. To redirect the standard output handle of a child process, the parent process performs the following steps:

1.Call the GetStdHandle function to get the current standard output handle; save the handle for later use.

2.Call the CreatePipe function to create an anonymous pipe. This function returns handles to the read and write ends of the pipe.

3.Call the SetStdHandle function to set its standard output to be the write handle of the pipe.

4.Call the CreateProcess function to create the child process. The child process inherits the inheritable handles of the parent process. It also inherits the values of the standard handles of its parent process, which it can retrieve using the GetStdHandle function.

5.Call the CloseHandle function to close the parent's handle to the write end of the pipe. After the child process inherits this handle, the parent process no longer needs its copy of the handle.

6.Call the ReadFile function to read from the pipe. This operation enables the parent process to read the data written to standard output by the child process.

The child process uses the GetStdHandle function to get its standard output handle, which is actually a handle to the write end of the pipe. The child process then uses the WriteFile function to write its output to the pipe.

Data is written to an anonymous pipe as a stream of bytes. This means that a process reading from a pipe cannot distinguish between the bytes written in separate write operations, unless both reading and writing processes use some protocol that lets the reading process know how many bytes to read. Typically, there is no protocol, so the reading process reads from the pipe until all write handles to the pipe are closed, which causes the ReadFile function to return FALSE. When a child process's standard output is redirected, the child process calls CloseHandle or terminates (which automatically closes the handle). Note that it is important for the parent process to close its handle to the write end of the pipe before trying to read from the pipe. Otherwise, its ReadFile operation cannot return FALSE because there is still an open handle to the write end of the pipe.

The procedure for redirecting standard input is similar to that for redirecting standard output, except that the pipe's read handle is used for the child's standard input. In this case, the parent process must ensure that the child process does not inherit the pipe's write handle. Otherwise, the ReadFile operation of the child process cannot return FALSE because the child process has an open handle to the write end of the pipe.

The parent process typically creates the read and write handles to the pipe so that they can be inherited by a child process. It does this by using CreatePipe, specifying a SECURITY_ATTRIBUTES structure with the bInheritHandle member set to TRUE. When a child's standard input is redirected, the child process should not inherit the pipe's write handle. The parent process prevents inheritance by using the DuplicateHandle function to create a noninheritable duplicate of the handle and then using CloseHandle to close the inheritable handle.

For an example program that uses anonymous pipes to redirect the standard handles of a child process, see Processes and Threads.