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