非阻塞伪终端,POLLHUP后恢复

Non blocking pseudo terminal, recovery after POLLHUP

我通过使用 open() 函数和 O_RDWR | O_NOCTTY | O_NONBLOCK 标志打开 /dev/ptmx 创建了一个新的伪终端。然后我使用 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() 函数 returns 始终带有 POLLHUP revents 标志。这是设计使然,但是我该怎么做才能使它像以前一样运行,即等待另一个进程打开并使用伪终端。我的意思是它等待,但是 returns 立即设置 POLLHUP 。另一方面,如果我关闭文件描述符,我无法保证在重新打开 /dev/ptmx 后会收到相同的伪终端 ID。有什么方法可以删除 POLLHUP revents 标志吗?

我发现了一个类似的问题:Poll() on Named Pipe returns with POLLHUP constantly and immediately,但是我已经按照那里的描述使用了 O_RDWR,但它对命名管道没有帮助。

创建伪终端后重新打开即可轻松解决问题。只要至少有一个作者存在,POLLHUP 就不会出现,所以我们可以自己用 open()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);