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

📄 00000015.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
#include&nbsp;&lt;sys/socket.h&gt;&nbsp;&nbsp;/*&nbsp;struct&nbsp;msghdr&nbsp;*/&nbsp;&nbsp;<BR>#include&nbsp;&lt;sys/uio.h&gt;&nbsp;&nbsp;&nbsp;/*&nbsp;struct&nbsp;iovec&nbsp;*/&nbsp;&nbsp;<BR>#include&nbsp;&lt;stddef.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&quot;ourhdr.h&quot;&nbsp;&nbsp;<BR>static&nbsp;struct&nbsp;cmsghdr&nbsp;*cmptr&nbsp;=&nbsp;NULL;&nbsp;&nbsp;/*&nbsp;malloc'ed&nbsp;first&nbsp;time&nbsp;*/&nbsp;&nbsp;<BR>#define&nbsp;CONTROLLEN&nbsp;(sizeof(struct&nbsp;cmsghdr)&nbsp;+&nbsp;sizeof(int))&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;/*&nbsp;size&nbsp;of&nbsp;control&nbsp;buffer&nbsp;to&nbsp;send/recv&nbsp;one&nbsp;file&nbsp;descriptor&nbsp;*/&nbsp;&nbsp;<BR>/*&nbsp;Receive&nbsp;a&nbsp;file&nbsp;descriptor&nbsp;from&nbsp;another&nbsp;process&nbsp;(a&nbsp;server).&nbsp;&nbsp;<BR>&nbsp;*&nbsp;In&nbsp;addition,&nbsp;any&nbsp;data&nbsp;received&nbsp;from&nbsp;the&nbsp;server&nbsp;is&nbsp;passed&nbsp;&nbsp;<BR>&nbsp;*&nbsp;to&nbsp;(*userfunc)(STDERR_FILENO,&nbsp;buf,&nbsp;nbytes).&nbsp;&nbsp;We&nbsp;have&nbsp;a&nbsp;&nbsp;<BR>&nbsp;*&nbsp;2-byte&nbsp;protocol&nbsp;for&nbsp;receiving&nbsp;the&nbsp;fd&nbsp;from&nbsp;send_fd().&nbsp;*/&nbsp;&nbsp;<BR>int&nbsp;&nbsp;<BR>recv_fd(int&nbsp;servfd,&nbsp;ssize_t&nbsp;(*userfunc)(int,&nbsp;const&nbsp;void&nbsp;*,&nbsp;size_t))&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;newfd,&nbsp;nread,&nbsp;status;&nbsp;&nbsp;<BR>&nbsp;char&nbsp;&nbsp;&nbsp;*ptr,&nbsp;buf[MAXLINE];&nbsp;&nbsp;<BR>&nbsp;struct&nbsp;iovec&nbsp;iov[1];&nbsp;&nbsp;<BR>&nbsp;struct&nbsp;msghdr&nbsp;msg;&nbsp;&nbsp;<BR>&nbsp;status&nbsp;=&nbsp;-1;&nbsp;&nbsp;<BR>&nbsp;for&nbsp;(&nbsp;;&nbsp;;&nbsp;)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;iov[0].iov_base&nbsp;=&nbsp;buf;&nbsp;&nbsp;<BR>&nbsp;&nbsp;iov[0].iov_len&nbsp;&nbsp;=&nbsp;sizeof(buf);&nbsp;&nbsp;<BR>&nbsp;&nbsp;msg.msg_iov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;iov;&nbsp;&nbsp;<BR>&nbsp;&nbsp;msg.msg_iovlen&nbsp;&nbsp;=&nbsp;1;&nbsp;&nbsp;<BR>&nbsp;&nbsp;msg.msg_name&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;NULL;&nbsp;&nbsp;<BR>&nbsp;&nbsp;msg.msg_namelen&nbsp;=&nbsp;0;&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(cmptr&nbsp;==&nbsp;NULL&nbsp;&amp;&amp;&nbsp;(cmptr&nbsp;=&nbsp;malloc(CONTROLLEN))&nbsp;==&nbsp;NULL)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;return(-1);&nbsp;&nbsp;<BR>&nbsp;&nbsp;msg.msg_control&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;(caddr_t)&nbsp;cmptr;&nbsp;&nbsp;<BR>&nbsp;&nbsp;msg.msg_controllen&nbsp;=&nbsp;CONTROLLEN;&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(&nbsp;(nread&nbsp;=&nbsp;recvmsg(servfd,&nbsp;&amp;msg,&nbsp;0))&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;err_sys(&quot;recvmsg&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;else&nbsp;if&nbsp;(nread&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;err_ret(&quot;connection&nbsp;closed&nbsp;by&nbsp;server&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;return(-1);&nbsp;&nbsp;<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;/*&nbsp;See&nbsp;if&nbsp;this&nbsp;is&nbsp;the&nbsp;final&nbsp;data&nbsp;with&nbsp;null&nbsp;&amp;&nbsp;status.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Null&nbsp;must&nbsp;be&nbsp;next&nbsp;to&nbsp;last&nbsp;byte&nbsp;of&nbsp;buffer,&nbsp;status&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte&nbsp;is&nbsp;last&nbsp;byte.&nbsp;&nbsp;Zero&nbsp;status&nbsp;means&nbsp;there&nbsp;must&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;a&nbsp;file&nbsp;descriptor&nbsp;to&nbsp;receive.&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;for&nbsp;(ptr&nbsp;=&nbsp;buf;&nbsp;ptr&nbsp;&lt;&nbsp;&amp;buf[nread];&nbsp;)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;if&nbsp;(*ptr++&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ptr&nbsp;!=&nbsp;&amp;buf[nread-1])&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_dump(&quot;message&nbsp;format&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status&nbsp;=&nbsp;*ptr&nbsp;&amp;&nbsp;255;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(status&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(msg.msg_controllen&nbsp;!=&nbsp;CONTROLLEN)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err_dump(&quot;status&nbsp;=&nbsp;0&nbsp;but&nbsp;no&nbsp;fd&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newfd&nbsp;=&nbsp;*(int&nbsp;*)CMSG_DATA(cmptr);&nbsp;/*&nbsp;new&nbsp;descriptor&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newfd&nbsp;=&nbsp;-status;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;nread&nbsp;-=&nbsp;2;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(nread&nbsp;&gt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;if&nbsp;((*userfunc)(STDERR_FILENO,&nbsp;buf,&nbsp;nread)&nbsp;!=&nbsp;nread)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return(-1);&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(status&nbsp;&gt;=&nbsp;0)&nbsp;/*&nbsp;final&nbsp;data&nbsp;has&nbsp;arrived&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;return(newfd);&nbsp;/*&nbsp;descriptor,&nbsp;or&nbsp;-status&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;}&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序15.10&nbsp;&nbsp;4.3BSD之下的recv_fd函数&nbsp;&nbsp;<BR>15.4&nbsp;Open服务器,版本1&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;使用文件描述符传送技术,现在我们开发一个open服务器:它是一个可执行程&nbsp;&nbsp;<BR>序,&nbsp;&nbsp;<BR>由一个进程执行以打开一个或多个文件。该服务器不是将这种文件送回调用进程,&nbsp;&nbsp;<BR>而是送回一个打开文件描述符。这使该服务器对任何类型的文件(例如调制解调器&nbsp;&nbsp;<BR>线,或一网络连接)而不单是普通文件都能起作用。这也意味着,用IPC交换最小&nbsp;&nbsp;<BR>量的信息--从客户到服务器传送文件名和打开方式,而从服务器到客户返回描述符&nbsp;&nbsp;<BR>。文件内容则不需用IPC传送。&nbsp;&nbsp;<BR>&nbsp;&nbsp;将服务器设计成一个单独的可执行程序有很多优点:&nbsp;&nbsp;<BR>1.&nbsp;任一客户都易于和服务器联系,这类似于客户调用一库函数。我们不需要将一&nbsp;&nbsp;<BR>特定服务编码在应用程序中,而是设计一种可供重用的设施。&nbsp;&nbsp;<BR>2.&nbsp;如若需要更改服务器,那么也只影响一道程序。相反,更新一库函数可能要更&nbsp;&nbsp;<BR>改调用此库函数的所有程序(用连编程序重新连接)。共享库函数可以简化这种更&nbsp;&nbsp;<BR>新。&nbsp;&nbsp;<BR>3.&nbsp;服务器可以是设置__用户__ID程序,于是使其具有客户没有的附加许可权。注&nbsp;&nbsp;<BR>意,一个库函数(或共享库函数)不能提供这种能力。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;客户进程创建一流管道,然后调用fork和exec以调用服务器。客户经流管道发&nbsp;&nbsp;<BR>送请求,服务器经管道回送响应。我们定义客户和服务器间的协议如下。&nbsp;&nbsp;<BR>1.&nbsp;客户经流管道向服务器发送下列形式的请求:&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;open&nbsp;&nbsp;&lt;pathname&gt;&nbsp;&nbsp;&lt;openmode&gt;\o&nbsp;&nbsp;<BR>&lt;openmode&gt;是open函数的第二个参数,以十进制表示。该请求字符串以null字节结&nbsp;&nbsp;<BR>尾。&nbsp;&nbsp;<BR>2.&nbsp;服务器调用send_fd&nbsp;或send_err回送一打开描述符或一条出错消息。这是一个&nbsp;&nbsp;<BR>进程向其父进程发送一打开描述符的实例。在15.6节,我们将修改此实例,其中使&nbsp;&nbsp;<BR>用了一个精灵服务器,它将一个描述符发送给完全无关的进程。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;程序15.11是头文件open.h,它包括标准系统头文件,并且定义了各个函数原&nbsp;&nbsp;<BR>型。&nbsp;&nbsp;<BR>#include&nbsp;&lt;sys/types.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&lt;errno.h&gt;&nbsp;&nbsp;<BR>。文件内容则不需用IPC传送。&nbsp;&nbsp;<BR>&nbsp;&nbsp;将服务器设计成一个单独的可执行程序有很多优点:&nbsp;&nbsp;<BR>1.&nbsp;任一客户都易于和服务器联系,这类似于客户调用一库函数。我们不需要将一&nbsp;&nbsp;<BR>特定服务编码在应用程序中,而是设计一种可供重用的设施。&nbsp;&nbsp;<BR>2.&nbsp;如若需要更改服务器,那么也只影响一道程序。相反,更新一库函数可能要更&nbsp;&nbsp;<BR>改调用此库函数的所有程序(用连编程序重新连接)。共享库函数可以简化这种更&nbsp;&nbsp;<BR>新。&nbsp;&nbsp;<BR>3.&nbsp;服务器可以是设置__用户__ID程序,于是使其具有客户没有的附加许可权。注&nbsp;&nbsp;<BR>意,一个库函数(或共享库函数)不能提供这种能力。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;客户进程创建一流管道,然后调用fork和exec以调用服务器。客户经流管道发&nbsp;&nbsp;<BR>送请求,服务器经管道回送响应。我们定义客户和服务器间的协议如下。&nbsp;&nbsp;<BR>1.&nbsp;客户经流管道向服务器发送下列形式的请求:&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;open&nbsp;&nbsp;&lt;pathname&gt;&nbsp;&nbsp;&lt;openmode&gt;\o&nbsp;&nbsp;<BR>&lt;openmode&gt;是open函数的第二个参数,以十进制表示。该请求字符串以null字节结&nbsp;&nbsp;<BR>尾。&nbsp;&nbsp;<BR>2.&nbsp;服务器调用send_fd&nbsp;或send_err回送一打开描述符或一条出错消息。这是一个&nbsp;&nbsp;<BR>进程向其父进程发送一打开描述符的实例。在15.6节,我们将修改此实例,其中使&nbsp;&nbsp;<BR>用了一个精灵服务器,它将一个描述符发送给完全无关的进程。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;程序15.11是头文件open.h,它包括标准系统头文件,并且定义了各个函数原&nbsp;&nbsp;<BR>型。&nbsp;&nbsp;<BR>#include&nbsp;&lt;sys/types.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&lt;errno.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&quot;ourhdr.h&quot;&nbsp;&nbsp;<BR>#define&nbsp;CL_OPEN&nbsp;&quot;open&quot;&nbsp;&nbsp;&nbsp;/*&nbsp;client's&nbsp;request&nbsp;for&nbsp;server&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;our&nbsp;function&nbsp;prototypes&nbsp;*/&nbsp;&nbsp;<BR>int&nbsp;&nbsp;csopen(char&nbsp;*,&nbsp;int);&nbsp;&nbsp;<BR>程序15.11&nbsp;&nbsp;open.h头文件&nbsp;&nbsp;<BR>程序15.12是main函数,其中包含一个循环,它先从标准输入读一个路径名,然后&nbsp;&nbsp;<BR>将该文件复制至标准输出。它调用函数csopen以与open&nbsp;服务器联系,从其返回一&nbsp;&nbsp;<BR>打开描述符。&nbsp;&nbsp;<BR>#include&nbsp;&quot;open.h&quot;&nbsp;&nbsp;<BR>#include&nbsp;&lt;fcntl.h&gt;&nbsp;&nbsp;<BR>#define&nbsp;BUFFSIZE&nbsp;8192&nbsp;&nbsp;<BR>int&nbsp;&nbsp;<BR>main(int&nbsp;argc,&nbsp;char&nbsp;*argv[])&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;int&nbsp;&nbsp;n,&nbsp;fd;&nbsp;&nbsp;<BR>&nbsp;char&nbsp;buf[BUFFSIZE],&nbsp;line[MAXLINE];&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;read&nbsp;filename&nbsp;to&nbsp;cat&nbsp;from&nbsp;stdin&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;while&nbsp;(fgets(line,&nbsp;MAXLINE,&nbsp;stdin)&nbsp;!=&nbsp;NULL)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;line[strlen(line)&nbsp;-&nbsp;1]&nbsp;=&nbsp;0;&nbsp;/*&nbsp;replace&nbsp;newline&nbsp;with&nbsp;null&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;open&nbsp;the&nbsp;file&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(&nbsp;(fd&nbsp;=&nbsp;csopen(line,&nbsp;O_RDONLY))&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;continue;&nbsp;/*&nbsp;csopen()&nbsp;prints&nbsp;error&nbsp;from&nbsp;server&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;and&nbsp;cat&nbsp;to&nbsp;stdout&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;while&nbsp;(&nbsp;(n&nbsp;=&nbsp;read(fd,&nbsp;buf,&nbsp;BUFFSIZE))&nbsp;&gt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;if&nbsp;(write(STDOUT_FILENO,&nbsp;buf,&nbsp;n)&nbsp;!=&nbsp;n)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;err_sys(&quot;write&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(n&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;err_sys(&quot;read&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;close(fd);&nbsp;&nbsp;<BR>&nbsp;}&nbsp;&nbsp;<BR>&nbsp;exit(0);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>程序15.12&nbsp;&nbsp;main&nbsp;函数&nbsp;&nbsp;<BR>程序15.13是函数csopen,它先创建一流管道,然后进行服务器的fork和exec操作&nbsp;&nbsp;<BR>。&nbsp;&nbsp;<BR>#include&nbsp;&quot;open.h&quot;&nbsp;&nbsp;<BR>#include&nbsp;&lt;sys/uio.h&gt;&nbsp;&nbsp;/*&nbsp;struct&nbsp;iovec&nbsp;*/&nbsp;&nbsp;<BR>/*&nbsp;Open&nbsp;the&nbsp;file&nbsp;by&nbsp;sending&nbsp;the&nbsp;&quot;name&quot;&nbsp;and&nbsp;&quot;oflag&quot;&nbsp;to&nbsp;the&nbsp;&nbsp;<BR>&nbsp;*&nbsp;connection&nbsp;server&nbsp;and&nbsp;reading&nbsp;a&nbsp;file&nbsp;descriptor&nbsp;back.&nbsp;*/&nbsp;&nbsp;<BR>int&nbsp;&nbsp;<BR>csopen(char&nbsp;*name,&nbsp;int&nbsp;oflag)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;pid_t&nbsp;&nbsp;&nbsp;pid;&nbsp;&nbsp;<BR>&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;len;&nbsp;&nbsp;<BR>&nbsp;char&nbsp;&nbsp;&nbsp;buf[10];&nbsp;&nbsp;<BR>&nbsp;struct&nbsp;iovec&nbsp;iov[3];&nbsp;&nbsp;<BR>&nbsp;static&nbsp;int&nbsp;&nbsp;fd[2]&nbsp;=&nbsp;{&nbsp;-1,&nbsp;-1&nbsp;};&nbsp;&nbsp;<BR>&nbsp;if&nbsp;(fd[0]&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;/*&nbsp;fork/exec&nbsp;our&nbsp;open&nbsp;server&nbsp;first&nbsp;time&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(s_pipe(fd)&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;err_sys(&quot;s_pipe&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(&nbsp;(pid&nbsp;=&nbsp;fork())&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;err_sys(&quot;fork&nbsp;error&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;else&nbsp;if&nbsp;(pid&nbsp;==&nbsp;0)&nbsp;{&nbsp;&nbsp;/*&nbsp;child&nbsp;*/&nbsp;&nbsp;<BR>

⌨️ 快捷键说明

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