首页 > 解决方案 > 非阻塞伪终端,POLLHUP 后恢复

问题描述

/dev/ptmx我通过使用open()函数和O_RDWR | O_NOCTTY | O_NONBLOCK标志打开来创建一个新的伪终端。然后我使用poll()函数等待来自远程端的传入数据:

struct pollfd pollFileDescriptors[numberOfTerminals];
for (unsigned terminalIndex = 0; terminalIndex < numberOfTerminals; terminalIndex++) {
    pollFileDescriptors[terminalIndex].fd = terminals[terminalIndex].getFileDescriptor();
    pollFileDescriptors[terminalIndex].events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND;
}

int ready = poll(pollFileDescriptors, terminals.getNumberOfTerminals(), timeoutMSec);

一切都像梦一样工作,直到远端关闭连接。在这种情况下,该poll()函数始终返回带有POLLHUPrevents 标志。这是设计使然,但是我可以做些什么让它像以前一样运行,即等待另一个进程打开并使用伪终端。我的意思是它会等待,但会立即返回POLLHUPset。另一方面,如果我关闭文件描述符,我无法保证在重新打开/dev/ptmx. 有没有办法删除POLLHUPrevents 标志?

我发现了一个类似的问题:Poll() on Named Pipe returns with POLLHUP constant and immediate,但是我已经使用了 O_RDWR ,如那里所述,但它在命名管道的情况下没有帮助。

标签: c++linuxpty

解决方案


这个问题可以通过在创建后立即重新打开伪终端来轻松解决。只要至少有一位作家存在,POLLHUP 就不会出现,因此我们可以自己使用open()and来做到这一点ptsname()

// Create a new pseudo terminal
int fileDescriptor = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_NONBLOCK);
grantpt(fileDescriptor);
unlockpt(fileDescriptor);

// Reopen it for write
const char *targetPath = ptsname(fileDescriptor);
int dummyWriterFileDescriptor = open(fileName.c_str(), O_WRONLY | O_NOCTTY | O_NONBLOCK);

推荐阅读