⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000014.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 2 页
字号:
管道,一个子进程,使子进程的标准输入成为管道的读端,然后exec用户喜爱的分&nbsp;&nbsp;<BR>页程序。程序14.2显示了如何实现这些操作。(本例要求在命令行中有一个参&nbsp;&nbsp;<BR>数说明要显示的文件的名称。通常,这种类型的程序要求在终端上显示的数据已经&nbsp;&nbsp;<BR>在存储器中。)&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;sys/wait.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;ourhdr.h&quot;&nbsp;&nbsp;<BR>#define&nbsp;DEF_PAGER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;/usr/bin/more&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;default&nbsp;pager&nbsp;program&nbsp;*/&nbsp;&nbsp;<BR>int&nbsp;&nbsp;<BR>main(int&nbsp;argc,&nbsp;char&nbsp;*argv[])&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n,&nbsp;fd[2];&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pid_t&nbsp;&nbsp;&nbsp;pid;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;line[MAXLINE],&nbsp;*pager,&nbsp;*argv0;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE&nbsp;&nbsp;&nbsp;&nbsp;*fp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(argc&nbsp;!=&nbsp;2)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_quit(&quot;usage:&nbsp;a.out&nbsp;&lt;pathname&gt;&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(&nbsp;(fp&nbsp;=&nbsp;fopen(argv[1],&nbsp;&quot;r&quot;))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;can't&nbsp;open&nbsp;%s&quot;,&nbsp;argv[1]);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(pipe(fd)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;pipe&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(&nbsp;(pid&nbsp;=&nbsp;fork())&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;fork&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp;(pid&nbsp;&gt;&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;parent&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fd[0]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;close&nbsp;read&nbsp;end&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;parent&nbsp;copies&nbsp;argv[1]&nbsp;to&nbsp;pipe&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(fgets(line,&nbsp;MAXLINE,&nbsp;fp)&nbsp;!=&nbsp;NULL)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;=&nbsp;strlen(line);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(write(fd[1],&nbsp;line,&nbsp;n)&nbsp;!=&nbsp;n)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;write&nbsp;error&nbsp;to&nbsp;pipe&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ferror(fp))&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;fgets&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fd[1]);&nbsp;&nbsp;&nbsp;/*&nbsp;close&nbsp;write&nbsp;end&nbsp;of&nbsp;pipe&nbsp;for&nbsp;reader&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(waitpid(pid,&nbsp;NULL,&nbsp;0)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;waitpid&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;child&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fd[1]);&nbsp;&nbsp;&nbsp;/*&nbsp;close&nbsp;write&nbsp;end&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(fd[0]&nbsp;!=&nbsp;STDIN_FILENO)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(dup2(fd[0],&nbsp;STDIN_FILENO)&nbsp;!=&nbsp;STDIN_FILENO)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;dup2&nbsp;error&nbsp;to&nbsp;stdin&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fd[0]);&nbsp;&nbsp;&nbsp;/*&nbsp;don't&nbsp;need&nbsp;this&nbsp;after&nbsp;dup2&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;get&nbsp;arguments&nbsp;for&nbsp;execl()&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(&nbsp;(pager&nbsp;=&nbsp;getenv(&quot;PAGER&quot;))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pager&nbsp;=&nbsp;DEF_PAGER;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(&nbsp;(argv0&nbsp;=&nbsp;strrchr(pager,&nbsp;'/'))&nbsp;!=&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argv0++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;step&nbsp;past&nbsp;rightmost&nbsp;slash&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argv0&nbsp;=&nbsp;pager;&nbsp;&nbsp;/*&nbsp;no&nbsp;slash&nbsp;in&nbsp;pager&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(execl(pager,&nbsp;argv0,&nbsp;(char&nbsp;*)&nbsp;0)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;execl&nbsp;error&nbsp;for&nbsp;%s&quot;,&nbsp;pager);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序14.2&nbsp;&nbsp;将文件复制到分页程序&nbsp;&nbsp;<BR>在调用fork之前先创建一个pipe。fork之后父进程关闭其读端,子进程关闭其写端&nbsp;&nbsp;<BR>。子进程然后调用dup2,使其标准输入成为管道的读端。当执行分页程序时,其标&nbsp;&nbsp;<BR>准输入将是管道的读端。&nbsp;&nbsp;<BR>当我们将一个描述符复制到另一个时(在子进程中,fd[0]复制到标准输入),应&nbsp;&nbsp;<BR>当注意该描述符的值并不已经是所希望的值。如果该描述符已经具有所希望的值,&nbsp;&nbsp;<BR>并且我们先调用dup2,然后close则将关闭在此进程中只有该单个描述符所代表的&nbsp;&nbsp;<BR>打开文件。(请回忆3.12节中所述,当dup2中的两个参数值相等时的操作。)在本&nbsp;&nbsp;<BR>程序中,如果shell没有打开标准输入,那么程序开始处的fopen应已使用描述符0&nbsp;&nbsp;<BR>,也就是最小末使用的描述符,所以fd[0]决不会等于标准输入。尽管如此,只要&nbsp;&nbsp;<BR>先调用dup2,然后close以复制一个描述符到另一个,作为一种保护性的编程措施&nbsp;&nbsp;<BR>,我们总是先将两个描述符进行比较。&nbsp;&nbsp;<BR>请注意,我们是如何使用环境变量PAGER而获得用户分页程序名称的。如果这种操&nbsp;&nbsp;<BR>作没有成功,则使用系统默认值。这是环境变量的常见用法。&nbsp;&nbsp;<BR>实例&nbsp;&nbsp;<BR>请回忆8.8节中的五个函数TELL_WAIT、TELL_PARENT、TELL_CHILD、WAIT_PARENT以&nbsp;&nbsp;<BR>及WAIT_CHILD。在程序10.17中,我们提供了一个使用信号的实现。程序14.3则是&nbsp;&nbsp;<BR>一个使用管道的实现。&nbsp;&nbsp;<BR>如图14.5所示,我们在fork之前创建了两个管道。&nbsp;&nbsp;<BR>图14.5&nbsp;&nbsp;用两个管道实现父-子进程的同步&nbsp;&nbsp;<BR>父进程在调用TELL_CHILD时经由上一个管道写一个字符&quot;P&quot;,子进程在调用TELL_P&nbsp;&nbsp;<BR>ARENT时,经由下一个管道写一个字符&quot;C&quot;。相应的WAIT_XXX函数调用read读一个字&nbsp;&nbsp;<BR>符,没有读到字符时阻塞(睡眠等待)。&nbsp;&nbsp;<BR>请注意,每一个管道都有一个额外的读取进程,这没有关系。也就是说除了子进程&nbsp;&nbsp;<BR>从pfd1[0]读取,父进程也有上一个管道的读端。因为父进程并没有执行对该管道&nbsp;&nbsp;<BR>的读操作,所以这不会产生任何影响。&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;ourhdr.h&quot;&nbsp;&nbsp;<BR>static&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pfd1[2],&nbsp;pfd2[2];&nbsp;&nbsp;<BR>void&nbsp;&nbsp;<BR>TELL_WAIT()&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(pipe(pfd1)&nbsp;&lt;&nbsp;0&nbsp;||&nbsp;pipe(pfd2)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;pipe&nbsp;error&quot;);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>void&nbsp;&nbsp;<BR>TELL_PARENT(pid_t&nbsp;pid)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(write(pfd2[1],&nbsp;&quot;c&quot;,&nbsp;1)&nbsp;!=&nbsp;1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;write&nbsp;error&quot;);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>void&nbsp;&nbsp;<BR>WAIT_PARENT(void)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;c;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(read(pfd1[0],&nbsp;&amp;c,&nbsp;1)&nbsp;!=&nbsp;1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;read&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(c&nbsp;!=&nbsp;'p')&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_quit(&quot;WAIT_PARENT:&nbsp;incorrect&nbsp;data&quot;);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>void&nbsp;&nbsp;<BR>TELL_CHILD(pid_t&nbsp;pid)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(write(pfd1[1],&nbsp;&quot;p&quot;,&nbsp;1)&nbsp;!=&nbsp;1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;write&nbsp;error&quot;);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>void&nbsp;&nbsp;<BR>WAIT_CHILD(void)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;c;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(read(pfd2[0],&nbsp;&amp;c,&nbsp;1)&nbsp;!=&nbsp;1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;read&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(c&nbsp;!=&nbsp;'c')&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_quit(&quot;WAIT_CHILD:&nbsp;incorrect&nbsp;data&quot;);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序14.3&nbsp;&nbsp;使父、子进程同步的例程&nbsp;&nbsp;<BR>14.3&nbsp;popen和pclose函数&nbsp;&nbsp;<BR>因为常见的操作是创建一个连到另一个进程的管道,然后读其输出或向其发送输入&nbsp;&nbsp;<BR>,所以标准I/O库为实现这些操作提供了两个函数popen和pclose。这两个函数实现&nbsp;&nbsp;<BR>的操作是;创建一个管道,fork一个子进程,关闭管道的不使用端,exec一个she&nbsp;&nbsp;<BR>ll以执行命令,等待命令终止。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&nbsp;&lt;stdio.h&gt;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE&nbsp;*popen(const&nbsp;&nbsp;char&nbsp;&nbsp;*cmdstring,&nbsp;&nbsp;const&nbsp;&nbsp;char&nbsp;&nbsp;*type);&nbsp;&nbsp;<BR>返回:若成功为文件指针,出错为NULL&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;pclose(FILE&nbsp;&nbsp;*fp);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回:cmdstring

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -