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

📄 00000019.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
y程序后介绍这两种方法。&nbsp;&nbsp;<BR>观看长时间运行程序的输出&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用任一个标准shell,我们都可以将一个需要长时间运行的程序放到后台运行。&nbsp;&nbsp;<BR>但是如果我们将该程序的标准输出重定向到一个文件,并且如果它产生的输出不多&nbsp;&nbsp;<BR>,我们就不能方便地监控程序的进展,这是因为标准的输入/输出库会将标准输出&nbsp;&nbsp;<BR>放在缓冲区中保存。我们看到的将只是成块的输出结果,有时甚至可能是8192字节&nbsp;&nbsp;<BR>一块。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果我们有源程序,我们可以加入fflush调用。另一种方法是,我们可以在pty程&nbsp;&nbsp;<BR>序下运行该程序,让标准输入/输出库认为输出是终端。图19.6说明了这个结构,&nbsp;&nbsp;<BR>我们将这个缓慢输出的程序称为slowout。从登录shell到pty进程的fort/exec箭头&nbsp;&nbsp;<BR>用虚线表示,以强调pty进程是作为后台任务运行的。&nbsp;&nbsp;<BR>19.3&nbsp;&nbsp;&nbsp;打开伪终端设备&nbsp;&nbsp;<BR>在SVR4和4.3+BSD系统中打开伪终端设备的方法有所不同。我们提供两个函数来处&nbsp;&nbsp;<BR>理所有细节:ptym_open用来打开下一个有效的伪终端主设备,ptys_open用来打开&nbsp;&nbsp;<BR>相应的从设备。&nbsp;&nbsp;<BR>图19.6&nbsp;&nbsp;使用伪终端运行一个缓慢输出的程序&nbsp;&nbsp;<BR>#include&nbsp;&quot;ourhdr.h&quot;&nbsp;&nbsp;<BR>int&nbsp;ptym_open(char&nbsp;*pts_name);&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;<BR>&nbsp;述符;否则返回-1&nbsp;&nbsp;<BR>int&nbsp;ptys_open(int&nbsp;fdm,&nbsp;char&nbsp;*pts_name);&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;<BR>&nbsp;述符;否则返回-1&nbsp;&nbsp;<BR>通常我们不直接调用这两个函数--函数pty_fork(19.4节)调用它们并fork出一个&nbsp;&nbsp;<BR>子进程。&nbsp;&nbsp;<BR>ptym_open决定下一个有效的伪终端主设备并打开该设备。这个调用必须分配一个&nbsp;&nbsp;<BR>数组来存放主设备或从设备的名称,并且如果调用成功,相应的主设备或从设备的&nbsp;&nbsp;<BR>名称会通过pts_name返回。这个名称和ptym_open返回的文件描述符将传给ptys_o&nbsp;&nbsp;<BR>pen,该函数用来打开一个从设备。&nbsp;&nbsp;<BR>在我们讲解pty_fork函数之后,使用两个函数来打开这两个设备的原因将会很明显&nbsp;&nbsp;<BR>。通常,一个进程调用ptym_open来打开一个主设备并且得到从设备的名称。该进&nbsp;&nbsp;<BR>程然后fork子进程,子进程在调用setid建立新的会话后调用ptys_open来打开从设&nbsp;&nbsp;<BR>备。这就是从设备如何成为子进程的控制终端的过程。&nbsp;&nbsp;<BR>19.1.1&nbsp;系统V的版本4&nbsp;&nbsp;<BR>所有在SVR4系统下的伪终端的流实现细节在AT&amp;T[1990d]的第十二章中有所说明。&nbsp;&nbsp;<BR>三个函数在下列手册页中描述:grantpt(3),unlockpt(3),和ptsname(3)。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;伪终端主设备是/dev/ptmx。这是一个流的增殖设备。这意味着当我们打开该增殖&nbsp;&nbsp;<BR>设备,其open例程自动决定第一个未被使用的伪终端主设备并打开这个设备。(在&nbsp;&nbsp;<BR>下一节我们将看到在Berkeley系统中,我们必须自己找到第一个未被使用的伪终端&nbsp;&nbsp;<BR>主设备。)&nbsp;&nbsp;<BR>_______________________________________________________________________&nbsp;&nbsp;<BR>________&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;sys/types.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;sys/stat.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;errno.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fcntl.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;stropts.h&gt;&nbsp;&nbsp;<BR>#include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;ourhdr.h&quot;&nbsp;&nbsp;<BR>extern&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*ptsname(int);&nbsp;&nbsp;/*&nbsp;prototype&nbsp;not&nbsp;in&nbsp;any&nbsp;system&nbsp;header&nbsp;*/&nbsp;&nbsp;<BR>int&nbsp;&nbsp;<BR>ptym_open(char&nbsp;*pts_name)&nbsp;&nbsp;<BR>{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;*ptr;&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;fdm;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcpy(pts_name,&nbsp;&quot;/dev/ptmx&quot;);&nbsp;&nbsp;/*&nbsp;in&nbsp;case&nbsp;open&nbsp;fails&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(&nbsp;(fdm&nbsp;=&nbsp;open(pts_name,&nbsp;O_RDWR))&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-1);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(grantpt(fdm)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;grant&nbsp;access&nbsp;to&nbsp;slave&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fdm);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-2);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(unlockpt(fdm)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;clear&nbsp;slave's&nbsp;lock&nbsp;flag&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fdm);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-3);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(&nbsp;(ptr&nbsp;=&nbsp;ptsname(fdm))&nbsp;==&nbsp;NULL)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;get&nbsp;slave's&nbsp;name&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fdm);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-4);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcpy(pts_name,&nbsp;ptr);&nbsp;&nbsp;/*&nbsp;return&nbsp;name&nbsp;of&nbsp;slave&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(fdm);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;return&nbsp;fd&nbsp;of&nbsp;master&nbsp;*/&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>int&nbsp;&nbsp;<BR>ptys_open(int&nbsp;fdm,&nbsp;char&nbsp;*pts_name)&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;fds;&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;following&nbsp;should&nbsp;allocate&nbsp;controlling&nbsp;terminal&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(&nbsp;(fds&nbsp;=&nbsp;open(pts_name,&nbsp;O_RDWR))&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fdm);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-5);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ioctl(fds,&nbsp;I_PUSH,&nbsp;&quot;ptem&quot;)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fdm);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fds);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-6);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ioctl(fds,&nbsp;I_PUSH,&nbsp;&quot;ldterm&quot;)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fdm);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fds);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-7);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ioctl(fds,&nbsp;I_PUSH,&nbsp;&quot;ttcompat&quot;)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fdm);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(fds);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-8);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(fds);&nbsp;&nbsp;<BR>}&nbsp;&nbsp;<BR>_______________________________________________________________________&nbsp;&nbsp;<BR>________&nbsp;&nbsp;<BR>程序19.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SVR4的伪终端打开函数&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们首先打开设备/dev/ptmx并得到伪终端主设备的文件描述符。打开这个主设备&nbsp;&nbsp;<BR>自动锁定了对应的从设备。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们然后调用grantpt来改变从设备的权限。执行如下操作:(a)将从设备的所&nbsp;&nbsp;<BR>有权改为有效用户ID;(b)将组所有权改为组tty;(c)将权限改为只允许user&nbsp;&nbsp;<BR>-read,user-write和group-write。将组所有权设置为tty并允许group-write权限&nbsp;&nbsp;<BR>是因为程序wall(1)和write(1)的组标识符被设置为组tty。调用函数grantpt执行&nbsp;&nbsp;<BR>/user/lib/pt_chmod。该程序的用户被设置为root因此它能够修改从设备的所有者&nbsp;&nbsp;<BR>和权限。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;函数unlockpt用来清除从设备的内部锁。在打开从设备前我们必须做这件事情。&nbsp;&nbsp;<BR>并且我们必须调用ptsname来得到从设备的名称。这个名称的格式是/dev/pts/NNN&nbsp;&nbsp;<BR>

⌨️ 快捷键说明

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