📄 00000019.htm
字号:
*/ <BR> noecho = 1; <BR> break; <BR> case 'i': /* ignore EOF on standard input */ <BR> ignoreeof = 1; <BR> break; <BR> case 'n': /* not interactive */ <BR> interactive = 0; <BR> break; <BR> case 'v': /* verbose */ <BR> verbose = 1; <BR> break; <BR> case '?': <BR> err_quit("unrecognized option: -%c", optopt); <BR> } <BR> } <BR> if (optind >= argc) <BR> err_quit("usage: pty [ -d driver -einv ] program [ arg ... ]"); <BR> if (interactive) { /* fetch current termios and window size */ <BR> if (tcgetattr(STDIN_FILENO, &orig_termios) < 0) <BR> err_sys("tcgetattr error on stdin"); <BR> if (ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &size) < 0) <BR> err_sys("TIOCGWINSZ error"); <BR> pid = pty_fork(&fdm, slave_name, &orig_termios, &size); <BR> } else <BR> pid = pty_fork(&fdm, slave_name, NULL, NULL); <BR> if (pid < 0) <BR> err_sys("fork error"); <BR> else if (pid == 0) { /* child */ <BR> if (noecho) <BR> set_noecho(STDIN_FILENO); /* stdin is slave pty */ <BR> if (execvp(argv[optind], &argv[optind]) < 0) <BR> err_sys("can't execute: %s", argv[optind]); <BR> } <BR> if (verbose) { <BR> err_quit("unrecognized option: -%c", optopt); <BR> } <BR> } <BR> if (optind >= argc) <BR> err_quit("usage: pty [ -d driver -einv ] program [ arg ... ]"); <BR> if (interactive) { /* fetch current termios and window size */ <BR> if (tcgetattr(STDIN_FILENO, &orig_termios) < 0) <BR> err_sys("tcgetattr error on stdin"); <BR> if (ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &size) < 0) <BR> err_sys("TIOCGWINSZ error"); <BR> pid = pty_fork(&fdm, slave_name, &orig_termios, &size); <BR> } else <BR> pid = pty_fork(&fdm, slave_name, NULL, NULL); <BR> if (pid < 0) <BR> err_sys("fork error"); <BR> else if (pid == 0) { /* child */ <BR> if (noecho) <BR> set_noecho(STDIN_FILENO); /* stdin is slave pty */ <BR> if (execvp(argv[optind], &argv[optind]) < 0) <BR> err_sys("can't execute: %s", argv[optind]); <BR> } <BR> if (verbose) { <BR> stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); <BR> stermios.c_oflag &= ~(ONLCR); <BR> /* also turn off NL to CR/NL mapping on output */ <BR> if (tcsetattr(fd, TCSANOW, &stermios) < 0) <BR> err_sys("tcsetattr error"); <BR>} <BR>_______________________________________________________________________ <BR>________ <BR>程序19.4 pty程序的main函数 <BR> 在下一节我们检测pty程序的不同使用时,将会探讨不同的行命令选项。 <BR> 在调用pty_fork前,我们取得了termios和winsize结构的值,将其传递给pty_fo <BR>rk。通过这种方法,伪终端从设备具有和现在的终端相同的初始状态。 <BR> 从pty_fork返回后,子进程关闭了伪终端从设备的回显,并调用execvp来执行命 <BR>令行指定的程序。所有的命令行选项将成为程序的选项。 <BR> 父进程在调用exit时执行原先设置的exit处理程序,它复原终端状态,将用户终 <BR>端设置为初始模式(可选)。我们将在下一节讨论do_driver函数。 <BR> 接下来父进程调用函数loop(程序19.5)。该函数仅仅是将所有标准输入拷贝到 <BR>伪终端主设备,并将伪终端主设备收到的所有内容拷贝到标准输出。同18.7节一样 <BR>,我们有两个选择--一个进程还是两个?为了有所区别,我们在这里使用两个进程 <BR>,尽管使用select或poll的单进程也是可行的。 <BR>_______________________________________________________________________ <BR>________ <BR>#include <sys/types.h> <BR>#include <signal.h> <BR>#include "ourhdr.h" <BR>#define BUFFSIZE 512 <BR>static void sig_term(int); <BR>static volatile sig_atomic_t sigcaught; /* set by signal handler */ <BR>void <BR>loop(int ptym, int ignoreeof) <BR>{ <BR> pid_t child; <BR> int nread; <BR> char buff[BUFFSIZE]; <BR> if ( (child = fork()) < 0) { <BR> err_sys("fork error"); <BR> } else if (child == 0) { /* child copies stdin to ptym */ <BR> for ( ; ; ) { <BR> if ( (nread = read(STDIN_FILENO, buff, BUFFSIZE)) < 0) <BR> err_sys("read error from stdin"); <BR> else if (nread == 0) <BR> break; /* EOF on stdin means we're done <BR>*/ <BR> if (writen(ptym, buff, nread) != nread) <BR> err_sys("writen error to master pty"); <BR> } <BR> /* We always terminate when we encounter an EOF on stdin <BR> <BR> but we only notify the parent if ignoreeof is 0. */ <BR> if (ignoreeof == 0) <BR> kill(getppid(), SIGTERM);  
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -