我有一个 Pseudo-terminal slave,它给了我Resource Temporarily Unavailable (11)的读/写错误。我一直无法解决这个问题,但直到一周前我才知道任何 pty 的。所以,我可能会遗漏一些明显的东西。
根据我的阅读,这可能是由调用read()
非阻塞 pty 引起的。但是,当我检查从属 ptyF_GETFL
之后open()
,该值显示它是一个阻塞文件描述符。
的输出F_GETFL
显示该O_NONBLOCK
标志已禁用,并且该O_RDWR
标志已启用:
printf("F_GETFL: %x\n", fcntl( slavefd, F_GETFL)); // outputs F_GETFL: 2
我什至尝试通过使用来确定它何时准备好将slavefd
其视为非阻塞文件。select()
但是,它只是每次都超时。
那么,如果设置为阻塞,为什么read()
将errno设置为Resource Temporarily Unavailable ?slavefd
看起来的标志F_GETFL
正确吗?我还能尝试什么来缩小这个问题的原因?
更新:(更多信息)
我还不确定,但我认为 pty 从设备节点被 pppd 以某种方式锁定。有人告诉我,您可以回显到 pty slave,这似乎是真的,除非 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 设备时,它将线路规程从更改N_TTY
为N_PPP
。这意味着当你open()
再read()
或write()
到从节点时,PPP 中间驱动程序正在被使用而不是 TTY 驱动程序。因此,aread()
和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;
}