【发布时间】:2012-08-07 15:29:43
【问题描述】:
我有一个伪终端从站,它给我一个读/写错误 Resource Temporarily Unavailable (11)。我一直无法解决这个问题,但直到一周前我才知道任何 pty 的。所以,我可能遗漏了一些明显的东西。
根据我的阅读,这可能是由于在非阻塞 pty 上调用 read() 引起的。但是,当我在open() 从属pty 之后检查F_GETFL 时,该值显示它是一个阻塞文件描述符。
F_GETFL 的输出显示O_NONBLOCK 标志被禁用,O_RDWR 标志被启用:
printf("F_GETFL: %x\n", fcntl( slavefd, F_GETFL)); // outputs F_GETFL: 2
我什至尝试将slavefd 视为非阻塞文件,方法是使用select() 来确定它何时准备就绪。但是,它每次都会超时。
那么,如果slavefd 设置为阻塞,为什么read() 将errno 设置为Resource Temporarily Unavailable? 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 设备时,它会将 line 规程 从 N_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 设置)
-
我尝试了你的建议,但遇到了错误
Socket operation on non-socket(88) -
对不起,如果我不清楚。我只是想知道您是否设置了超时,因为这是 read() 可以返回 EAGAIN 的另一种情况。但看起来情况并非如此。