美文网首页LinuxLinux学习之路读书笔记
APUE读书笔记-19伪终端(16)

APUE读书笔记-19伪终端(16)

作者: QuietHeart | 来源:发表于2020-10-13 17:00 被阅读0次

    (7)pty程序的do_driver函数

    #include "apue.h"
    void do_driver(char *driver)
    {
        pid_t   child;
        int     pipe[2];
    
        /*
         * Create a stream pipe to communicate with the driver.
         */
        if (s_pipe(pipe) < 0)
            err_sys("can't create stream pipe");
    
        if ((child = fork()) < 0) {
            err_sys("fork error");
        } else if (child == 0) {        /* child */
            close(pipe[1]);
    
            /* stdin for driver */
            if (dup2(pipe[0], STDIN_FILENO) != STDIN_FILENO)
                err_sys("dup2 error to stdin");
    
            /* stdout for driver */
            if (dup2(pipe[0], STDOUT_FILENO) != STDOUT_FILENO)
                err_sys("dup2 error to stdout");
            if (pipe[0] != STDIN_FILENO && pipe[0] != STDOUT_FILENO)
                close(pipe[0]);
    
            /* leave stderr for driver alone */
            execlp(driver, driver, (char *)0);
            err_sys("execlp error for: %s", driver);
        }
        close(pipe[0]);     /* parent */
        if (dup2(pipe[1], STDIN_FILENO) != STDIN_FILENO)
            err_sys("dup2 error to stdin");
        if (dup2(pipe[1], STDOUT_FILENO) != STDOUT_FILENO)
            err_sys("dup2 error to stdout");
        if (pipe[1] != STDIN_FILENO && pipe[1] != STDOUT_FILENO)
            close(pipe[1]);
    
        /*
         * Parent returns, but with stdin and stdout connected
         * to the driver.
         */
    }
    

    通过我们自己写的被pty调用的driver程序,我们可以以任何需要的方式来驱动交互程序。即使它的标准输入和标准输出连接到pty上面,driver进程也还是可以通过读写/dev/tty来和用户进行交互。这个方案还是不如expect程序通用,但是它只通过不到50行的代码,就为pty程序添加了一个有用的选项。

    译者注

    原文参考

    参考: APUE2/ch19lev1sec6.html

    7、高级特性

    伪终端还有一些额外的特性,我们这里简单对它们列出。这些特性在Sun Microsystems和BSD的pty的man手册第4节中描述了。

    包模式

    包模式可以让PTY master获知PTY slave的状态变化。在Solaris上面,这个模式通过向PTY master端推送pckt的STREAMS模块来实现。我们在前面第2节中的"Solaris下面伪终端的结构"图中,对其进行了展示。在FreeBSD, Linux, 和 Mac OS X中,这个模式通过ioctl的TIOCPKT命令来激活。

    Solaris和其他平台的包模式细节有一些不同。Solaris下面,由于pckt模块将特定的事件转化成非数据的STREAMS消息,所以从PTY master读取的进程需要调用getmsg来获得来自stream头的消息。在其他平台下面,每次从PTY master读取都会返回一个状态字节接着一个可选的数据。

    除去这些实现上面的细节,包模式的目的就是在PTY slave上面的行规则模块发生如下事件的时候,通知读取PTY master的进程:当读取队列被flushed,当写队列被flushed,当输出停止的时候(例如Control-S导致其停止),当输出重新启动的时候,当XON/XOFF流控制在被禁止之后再次被使能的时候,在XON/XOFF流控制在被使能之后又被禁止的时候。这些事件,在诸如rlogin客户和rlogind服务进程中可能会被用到。

    相关文章

      网友评论

        本文标题:APUE读书笔记-19伪终端(16)

        本文链接:https://www.haomeiwen.com/subject/scxluktx.html