伪终端(pty)报告资源暂时不可用

3
我有一个伪终端从设备,它给我返回了一个读/写错误,错误信息为“资源暂时不可用(11)”。我一直无法解决这个问题,但在一周前我还不知道什么是pty。所以,我可能会错过一些显而易见的东西。
根据我的阅读,这可能是由于在非阻塞的pty上调用read()引起的。然而,当我在打开从设备pty后检查F_GETFL时,值显示它是一个阻塞文件描述符。
F_GETFL的输出显示O_NONBLOCK标志被禁用,O_RDWR标志被启用:
printf("F_GETFL: %x\n", fcntl( slavefd, F_GETFL)); // outputs F_GETFL: 2

我甚至尝试使用select()slavefd视为非阻塞文件,以确定何时准备就绪。但是,它每次都超时。

那么,如果将slavefd设置为阻塞状态,为什么read()会将errno设置为“资源暂时不可用”?F_GETFL的标志是否正确?还有什么其他方法可以尝试缩小此问题的原因?

更新:(更多信息)

我还不确定,但我认为pty从设备节点正在某种程度上被pppd锁定。我被告知可以向pty从设备中echo,这似乎是正确的,除了当pppd在使用它时。

更新2:(添加代码)

if (argc!=2)
    return;

printf("opening %s\n", argv[1]);
slavefd = open(argv[1], O_RDWR );
if (slavefd < 0)
    return;

这个更新展示了我如何打开从设备。因为我正在使用这个应用来调试,所以我直接使用argv[1]

问题解决:

我尝试读写的从节点被pppd修改了。当pppd控制一个tty/pty设备时,它会将line disciplineN_TTY更改为N_PPP。这意味着当你open()然后read()write()从从节点读取或写入时,PPP中间驱动程序被使用而不是TTY驱动程序。所以,read()write()归结为完全不同的函数。查看N_PPP驱动程序,我找到了以下内容。这回答了我的问题,为什么会返回EAGAIN。

/*
 * Read does nothing - no data is ever available this way.
 * Pppd reads and writes packets via /dev/ppp instead.
 */
static ssize_t
ppp_asynctty_read(struct tty_struct *tty, struct file *file,
          unsigned char __user *buf, size_t count)
{
    return -EAGAIN;
}

/*
 * Write on the tty does nothing, the packets all come in
 * from the ppp generic stuff.
 */
static ssize_t
        ppp_asynctty_write(struct tty_struct *tty, struct file *file,
           const unsigned char *buf, size_t count)
{
    return -EAGAIN;
}

你设置了接收超时吗?(使用setsockopt设置) - craig65535
我尝试了你的建议,但遇到了错误 Socket operation on non-socket(88) - rkyser
抱歉如果我表达不清楚。我只是想知道你是否设置了超时,因为这是另一种情况,read() 可能会返回 EAGAIN。但看起来这不是这种情况。 - craig65535
1个回答

1
我试图读/写的从节点正在被pppd修改。当pppd控制一个tty/pty设备时,它会将“行规程”从“N_TTY”更改为“N_PPP”。这意味着当您打开()并然后读取()或写入()从节点时,PPP中间驱动程序正在使用而不是TTY驱动程序。因此,read()和write()归结为完全不同的函数。查看N_PPP驱动程序,我发现以下内容。这回答了我的问题,即为什么返回EAGAIN。
/*
 * Read does nothing - no data is ever available this way.
 * Pppd reads and writes packets via /dev/ppp instead.
 */
static ssize_t
ppp_asynctty_read(struct tty_struct *tty, struct file *file,
          unsigned char __user *buf, size_t count)
{
    return -EAGAIN;
}

/*
 * Write on the tty does nothing, the packets all come in
 * from the ppp generic stuff.
 */
static ssize_t
        ppp_asynctty_write(struct tty_struct *tty, struct file *file,
           const unsigned char *buf, size_t count)
{
    return -EAGAIN;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接