【问题标题】:Read timeout on pty file descriptor failingpty 文件描述符读取超时失败
【发布时间】:2012-06-01 06:51:17
【问题描述】:

我正在尝试在代表 PTY 的文件描述符上设置读取超时。我在 termios 中设置了 VMIN = 0 和 VTIME = 10,我希望在字符可用时返回,或者如果没有字符可用,则在一秒钟后返回。但是,我的程序永远处于读取调用中。

PTY 是否有什么特别之处使其无法正常工作?是否有其他 TERMIOS 设置导致此设置起作用?我在标准输入文件描述符上尝试了相同的配置,它按预期工作。

#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <fcntl.h>

#define debug(...) fprintf (stderr, __VA_ARGS__)

static void set_term (int fd)
{
    struct termios termios;
    int res;

    res = tcgetattr (fd, &termios);
    if (res) {
        debug ("TERM get error\n");
        return;
    }

    cfmakeraw (&termios);
    termios.c_lflag &= ~(ICANON);
    termios.c_cc[VMIN] = 0;
    termios.c_cc[VTIME] = 10;        /* One second */

    res = tcsetattr (fd, TCSANOW, &termios);
    if (res) {
        debug ("TERM set error\n");
        return;
    }

}

int get_term (void)
{
    int fd;
    int res;
    char *name;

    fd = posix_openpt (O_RDWR);
    if (fd < 0) {
        debug ("Error opening PTY\n");
        exit (1);
    }

    res = grantpt (fd);
    if (res) {
        debug ("Error granting PTY\n");
        exit (1);
    }

    res = unlockpt (fd);
    if (res) {
        debug ("Error unlocking PTY\n");
        exit (1);
    }

    name = ptsname (fd);
    debug ("Attach terminal on %s\n", name);

    return fd;
}

int main (int argc, char **argv)
{
    int read_fd;
    int bytes;
    char c;

    read_fd = get_term ();

    set_term (read_fd);
    bytes = read (read_fd, &c, 1);
    debug ("Read returned\n");

    return 0;
}

【问题讨论】:

    标签: linux pty termios


    【解决方案1】:

    来自 linux pty (7) 联机帮助页(斜体是我的):

    伪终端(有时缩写为“pty”)是一对虚拟字符设备, 提供双向通信通道。通道的一端称为 掌握;另一端称为奴隶。 伪终端的从端提供 一个与经典终端完全一样的界面

    但是,您的程序正在从 主设备 中读取,不能期望它的行为与终端设备完全相同

    如果您因此更改/扩展get_term 的最后几行...

    int slave_fd =  open (name, O_RDWR); /* now open the slave end..*/
    if (slave_fd < 0) {
       debug ("Error opening slave PTY\n");
       exit (1);
    }
    
    return slave_fd; /* ... and use it instead of the master..*/
    

    ...您的示例程序将按预期运行。

    【讨论】:

    • 当然,这引出了一个问题,为什么 Faz 的原始程序中 master 上的 tcsetattr() 会成功,以及它究竟实现了什么。我相信(但在任何地方都找不到此文档)它设置了 slave 终端属性。在任何情况下,示例程序中的 tcsetattr() 使用的两个文件描述符中的哪一个对其行为没有任何影响,只要在从端完成读取。
    • 更多关于 Solaris 和 Linux 上主从之间的区别here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多