📄 00000019.htm
字号:
管理者的子进程并使其具有控制终端。 <BR>#include <sys/types.h> <BR>#include <termios.h> <BR>#include <sys/ioctl.h> /* 4.3+BSD系统中,在这里定义了winsize结构 */ <BR>#include <ourhdr.h> <BR>pid_t pty_fork(int *ptrfdm, char *slave_name, <BR> const struct termios *slave_termios, <BR> const struct winsize *slave_winsize); <BR>返回:在子进程返回0;在父进程返回子进程的进程ID;遇到错误返回-1 <BR>Pty主设备的文件描述符通过ptrfdm指针返回。 <BR>如果slave_name不为空,从设备的名称被存放在该指针指向的存储区中。调用者必 <BR>须为该存储区分配空间。 <BR>如果指针slave_termios不为空,该指针所引用的结构将从设备的终端行规程初始 <BR>化。如果该指针为空,系统将从设备的termios结构初始化为一个由具体应用定义 <BR>的初始状态。类似的,如果slave_winsize指针不为空,该指针所引用的结构将从 <BR>设备的窗口大小初始化。如果该指针为空,winsize结构通常被初始化为0。 <BR>程序19.3显示了这个程序的代码。调用相应的ptym_open和ptys_open函数,这个函 <BR>数在SVR4和4.3+BSD系统下都可以使用。 <BR>在打开伪终端主设备后,fork将被调用。正如前面提到的,我们要等到调用setid <BR>建立新的会话后才调用ptys_open。当调用setid时,子进程还不是一个进程组的l <BR>eader(想一想为什么?)因此第9.5节列出的三个操作被使用:(a)子进程作为 <BR>对话的管理者创建一个新的对话;(b)子进程创建一个新的进程组;(c)子进程 <BR>没有控制终端。在SVR4系统中,当调用ptys_open时,从设备成为了控制终端。在 <BR>4.3+BSD系统中,我们必须调用ioctl并使用参数TIOCSCTTY来分配一个控制终端。 <BR>然后termios和winsize这两个结构在子进程中被初始化。最后从设备的文件描述符 <BR>被复制到子进程的标准输入、标准输出和标准出错中。这表示由子进程所exec的进 <BR>程都会将上述三个句柄同伪终端从设备联系起来。 <BR>在调用fork后,父进程返回伪终端主设备的描述符并返回。在下一节我们将在pty <BR>程序中使用pty_fork。 <BR>_______________________________________________________________________ <BR>________ <BR>#include <sys/types.h> <BR>#include <termios.h> <BR>#ifndef TIOCGWINSZ <BR>#include <sys/ioctl.h> /* 44BSD requires this too */ <BR>#endif <BR>#include "ourhdr.h" <BR>pid_t <BR>pty_fork(int *ptrfdm, char *slave_name, <BR> const struct termios *slave_termios, <BR> const struct winsize *slave_winsize) <BR>{ <BR> int fdm, fds; <BR> pid_t pid; <BR> char pts_name[20]; <BR> if ( (fdm = ptym_open(pts_name)) < 0) <BR> err_sys("can't open master pty: %s", pts_name); <BR> if (slave_name != NULL) <BR> strcpy(slave_name, pts_name); /* return name of slave */ <BR> if ( (pid = fork()) < 0) <BR> return(-1); <BR> else if (pid == 0) { /* child */ <BR> if (setsid() < 0) <BR> err_sys("setsid error"); <BR> /* SVR4 acquires controlling terminal on <BR>open() */ <BR> if ( (fds = ptys_open(fdm, pts_name)) < 0) <BR> err_sys("can't open slave pty"); <BR> err_sys("dup2 error to stderr"); <BR> if (fds > STDERR_FILENO) <BR> close(fds); <BR> return(0); /* child returns 0 just like fork() */ <BR> } else { /* parent */ <BR> *ptrfdm = fdm; /* return fd of master */ <BR> return(pid); /* parent returns pid of child */ <BR> } <BR>} <BR>_______________________________________________________________________ <BR>________ <BR>程序19.3 pty_fork函数 <BR>19.5 pty程序 <BR>写pty程序的目的是为了用键入 <BR> pty prog arg1 arg2 <BR>来代替 <BR> prog arg1 arg2 <BR> 这样使我们可以用pty来执行另一个程序,该程序在一个自己的会话中执行,并和 <BR>一个伪终端连接。 <BR> 让我们看以下pty程序的源代码。程序19.4包含main函数。它调用上一节的pty_f <BR>ork函数。 <BR>_______________________________________________________________________ <BR>________ <BR>#include <sys/types.h> <BR>#include <termios.h> <BR>#ifndef TIOCGWINSZ <BR>#include <sys/ioctl.h> /* 44BSD requires this too */ <BR>#endif <BR>#include "ourhdr.h" <BR>static void set_noecho(int); /* at the end of this file */ <BR>void do_driver(char *); /* in the file driver.c */ <BR>void loop(int, int); /* in the file loop.c */ <BR>int <BR>main(int argc, char *argv[]) <BR>{ <BR> int fdm, c, ignoreeof, interactive, noecho, <BR>erbose; <BR> pid_t pid; <BR> char *driver, slave_name[20]; <BR> struct termios orig_termios; <BR> struct winsize size; <BR> interactive = isatty(STDIN_FILENO); <BR> ignoreeof = 0; <BR> noecho = 0; <BR> verbose = 0; <BR> driver = NULL; <BR> opterr = 0; /* don't want getopt() writing to stderr */ <BR> while ( (c = getopt(argc, argv, "d:einv")) != EOF) { <BR> switch (c) { <BR> case 'd': /* driver for stdin/stdout */ <BR> driver = optarg; <BR> break; <BR> case 'e': /* noecho for slave pty's line disciplin <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -