📄 library_14.html
字号:
<!-- This HTML file has been created by texi2html 1.27 from library.texinfo on 3 March 1994 --><TITLE>The GNU C Library - Pipes and FIFOs</TITLE><P>Go to the <A HREF="library_13.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_13.html">previous</A>, <A HREF="library_15.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_15.html">next</A> section.<P><H1><A NAME="SEC211" HREF="library_toc.html#SEC211" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC211">Pipes and FIFOs</A></H1><A NAME="IDX873"></A><P>A <DFN>pipe</DFN> is a mechanism for interprocess communication; data writtento the pipe by one process can be read by another process. The data ishandled in a first-in, first-out (FIFO) order. The pipe has no name; itis created for one use and both ends must be inherited from the singleprocess which created the pipe.<A NAME="IDX874"></A><P>A <DFN>FIFO special file</DFN> is similar to a pipe, but instead of being ananonymous, temporary connection, a FIFO has a name or names like anyother file. Processes open the FIFO by name in order to communicatethrough it.<P>A pipe or FIFO has to be open at both ends simultaneously. If you readfrom a pipe or FIFO file that doesn't have any processes writing to it(perhaps because they have all closed the file, or exited), the readreturns end-of-file. Writing to a pipe or FIFO that doesn't have areading process is treated as an error condition; it generates a<CODE>SIGPIPE</CODE> signal, and fails with error code <CODE>EPIPE</CODE> if thesignal is handled or blocked.<P>Neither pipes nor FIFO special files allow file positioning. Bothreading and writing operations happen sequentially; reading from thebeginning of the file and writing at the end.<P><A NAME="IDX875"></A><A NAME="IDX876"></A><A NAME="IDX877"></A><H2><A NAME="SEC212" HREF="library_toc.html#SEC212" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC212">Creating a Pipe</A></H2><P>The primitive for creating a pipe is the <CODE>pipe</CODE> function. Thiscreates both the reading and writing ends of the pipe. It is not veryuseful for a single process to use a pipe to talk to itself. In typicaluse, a process creates a pipe just before it forks one or more childprocesses (see section <A HREF="library_23.html#SEC405" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html#SEC405">Creating a Process</A>). The pipe is then used forcommunication either between the parent or child processes, or betweentwo sibling processes.<P>The <CODE>pipe</CODE> function is declared in the header file<TT>`unistd.h'</TT>.<A NAME="IDX878"></A><P><A NAME="IDX879"></A><U>Function:</U> int <B>pipe</B> <I>(int <VAR>filedes</VAR><TT>[2]</TT>)</I><P>The <CODE>pipe</CODE> function creates a pipe and puts the file descriptorsfor the reading and writing ends of the pipe (respectively) into<CODE><VAR>filedes</VAR>[0]</CODE> and <CODE><VAR>filedes</VAR>[1]</CODE>.<P>An easy way to remember that the input end comes first is that filedescriptor <CODE>0</CODE> is standard input, and file descriptor <CODE>1</CODE> isstandard output.<P>If successful, <CODE>pipe</CODE> returns a value of <CODE>0</CODE>. On failure,<CODE>-1</CODE> is returned. The following <CODE>errno</CODE> error conditions aredefined for this function:<P><DL COMPACT><DT><CODE>EMFILE</CODE><DD>The process has too many files open.<P><DT><CODE>ENFILE</CODE><DD>There are too many open files in the entire system. See section <A HREF="library_2.html#SEC16" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_2.html#SEC16">Error Codes</A>,for more information about <CODE>ENFILE</CODE>.</DL><P>Here is an example of a simple program that creates a pipe. This programuses the <CODE>fork</CODE> function (see section <A HREF="library_23.html#SEC405" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html#SEC405">Creating a Process</A>) to createa child process. The parent process writes data to the pipe, which isread by the child process.<P><PRE>#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>/* Read characters from the pipe and echo them to <CODE>stdout</CODE>. */void read_from_pipe (int file){ FILE *stream; int c; stream = fdopen (file, "r"); while ((c = fgetc (stream)) != EOF) putchar (c); fclose (stream);}/* Write some random text to the pipe. */void write_to_pipe (int file){ FILE *stream; stream = fdopen (file, "w"); fprintf (stream, "hello, world!\n"); fprintf (stream, "goodbye, world!\n"); fclose (stream);}intmain (void){ pid_t pid; int mypipe[2]; /* Create the pipe. */ if (pipe (mypipe)) { fprintf (stderr, "Pipe failed.\n"); return EXIT_FAILURE; } /* Create the child process. */ pid = fork (); if (pid == (pid_t) 0) { /* This is the child process. */ read_from_pipe (mypipe[0]); return EXIT_SUCCESS; } else if (pid < (pid_t) 0) { /* The fork failed. */ fprintf (stderr, "Fork failed.\n"); return EXIT_FAILURE; } else { /* This is the parent process. */ write_to_pipe (mypipe[1]); return EXIT_SUCCESS; }}</PRE><P><A NAME="IDX880"></A><A NAME="IDX881"></A><A NAME="IDX882"></A><H2><A NAME="SEC213" HREF="library_toc.html#SEC213" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC213">Pipe to a Subprocess</A></H2><P>A common use of pipes is to send data to or receive data from a programbeing run as subprocess. One way of doing this is by using a combination of<CODE>pipe</CODE> (to create the pipe), <CODE>fork</CODE> (to create the subprocess),<CODE>dup2</CODE> (to force the subprocess to use the pipe as its standard inputor output channel), and <CODE>exec</CODE> (to execute the new program). Or,you can use <CODE>popen</CODE> and <CODE>pclose</CODE>.<P>The advantage of using <CODE>popen</CODE> and <CODE>pclose</CODE> is that theinterface is much simpler and easier to use. But it doesn't offer asmuch flexibility as using the low-level functions directly.<P><A NAME="IDX883"></A><U>Function:</U> FILE * <B>popen</B> <I>(const char *<VAR>command</VAR>, const char *<VAR>mode</VAR>)</I><P>The <CODE>popen</CODE> function is closely related to the <CODE>system</CODE>function; see section <A HREF="library_23.html#SEC402" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_23.html#SEC402">Running a Command</A>. It executes the shell command<VAR>command</VAR> as a subprocess. However, instead of waiting for thecommand to complete, it creates a pipe to the subprocess and returns astream that corresponds to that pipe.<P>If you specify a <VAR>mode</VAR> argument of <CODE>"r"</CODE>, you can read from the stream to retrieve data from the standard output channel of the subprocess.The subprocess inherits its standard input channel from the parent process.<P>Similarly, if you specify a <VAR>mode</VAR> argument of <CODE>"w"</CODE>, you canwrite to the stream to send data to the standard input channel of thesubprocess. The subprocess inherits its standard output channel fromthe parent process.<P>In the event of an error, <CODE>popen</CODE> returns a null pointer. Thismight happen if the pipe or stream cannot be created, if the subprocesscannot be forked, or if the program cannot be executed.<P><A NAME="IDX884"></A><U>Function:</U> int <B>pclose</B> <I>(FILE *<VAR>stream</VAR>)</I><P>The <CODE>pclose</CODE> function is used to close a stream created by <CODE>popen</CODE>.It waits for the child process to terminate and returns its status value,as for the <CODE>system</CODE> function.<P>Here is an example showing how to use <CODE>popen</CODE> and <CODE>pclose</CODE> tofilter output through another program, in this case the paging program<CODE>more</CODE>.<P><PRE>#include <stdio.h>#include <stdlib.h>void write_data (FILE * stream){ int i; for (i = 0; i < 100; i++) fprintf (stream, "%d\n", i); if (ferror (stream)) { fprintf (stderr, "Output to stream failed.\n"); exit (EXIT_FAILURE); }}intmain (void){ FILE *output; output = popen ("more", "w"); if (!output) { fprintf (stderr, "Could not run more.\n"); return EXIT_FAILURE; } write_data (output); pclose (output); return EXIT_SUCCESS;}</PRE><P><A NAME="IDX885"></A><A NAME="IDX886"></A><H2><A NAME="SEC214" HREF="library_toc.html#SEC214" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC214">FIFO Special Files</A></H2><P>A FIFO special file is similar to a pipe, except that it is created in adifferent way. Instead of being an anonymous communications channel, aFIFO special file is entered into the file system by calling<CODE>mkfifo</CODE>.<P>Once you have created a FIFO special file in this way, any process canopen it for reading or writing, in the same way as an ordinary file.However, it has to be open at both ends simultaneously before you canproceed to do any input or output operations on it. Opening a FIFO forreading normally blocks until some other process opens the same FIFO forwriting, and vice versa.<P>The <CODE>mkfifo</CODE> function is declared in the header file<TT>`sys/stat.h'</TT>.<A NAME="IDX887"></A><P><A NAME="IDX888"></A><U>Function:</U> int <B>mkfifo</B> <I>(const char *<VAR>filename</VAR>, mode_t <VAR>mode</VAR>)</I><P>The <CODE>mkfifo</CODE> function makes a FIFO special file with name<VAR>filename</VAR>. The <VAR>mode</VAR> argument is used to set the file'spermissions; see section <A HREF="library_13.html#SEC207" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_13.html#SEC207">Assigning File Permissions</A>.<P>The normal, successful return value from <CODE>mkfifo</CODE> is <CODE>0</CODE>. Inthe case of an error, <CODE>-1</CODE> is returned. In addition to the usualfile name syntax errors (see section <A HREF="library_10.html#SEC115" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_10.html#SEC115">File Name Errors</A>), the following<CODE>errno</CODE> error conditions are defined for this function:<P><DL COMPACT><DT><CODE>EEXIST</CODE><DD>The named file already exists.<P><DT><CODE>ENOSPC</CODE><DD>The directory or file system cannot be extended.<P><DT><CODE>EROFS</CODE><DD>The directory that would contain the file resides on a read-only filesystem.</DL><P><H2><A NAME="SEC215" HREF="library_toc.html#SEC215" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC215">Atomicity of Pipe I/O</A></H2><P>Reading or writing pipe data is <DFN>atomic</DFN> if the size of data writtenis less than <CODE>PIPE_BUF</CODE>. This means that the data transfer seemsto be an instantaneous unit, in that nothing else in the system canobserve a state in which it is partially complete. Atomic I/O may notbegin right away (it may need to wait for buffer space or for data), butonce it does begin, it finishes immediately.<P>Reading or writing a larger amount of data may not be atomic; forexample, output data from other processes sharing the descriptor may beinterspersed.<P>See section <A HREF="library_27.html#SEC463" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_27.html#SEC463">Limits on File System Capacity</A>, for information about the <CODE>PIPE_BUF</CODE>parameter.<P>Go to the <A HREF="library_13.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_13.html">previous</A>, <A HREF="library_15.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_15.html">next</A> section.<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -