c++ - 非阻塞伪终端,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()
函数始终返回带有POLLHUP
revents 标志。这是设计使然,但是我可以做些什么让它像以前一样运行,即等待另一个进程打开并使用伪终端。我的意思是它会等待,但会立即返回POLLHUP
set。另一方面,如果我关闭文件描述符,我无法保证在重新打开/dev/ptmx
. 有没有办法删除POLLHUP
revents 标志?
我发现了一个类似的问题:Poll() on Named Pipe returns with POLLHUP constant and immediate,但是我已经使用了 O_RDWR ,如那里所述,但它在命名管道的情况下没有帮助。
解决方案
这个问题可以通过在创建后立即重新打开伪终端来轻松解决。只要至少有一位作家存在,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);
推荐阅读
- kubernetes - Kubernetes:是否可以在 GKE 区域集群中获取主节点 IP/名称
- ibm-midrange - IBM i 确定可用的编程语言
- python - 使用 python 实现 Excel 自动化
- android - Schedulers.io() 在我的单元测试中抛出 NullPointerException
- ocaml - 当我错误地实现了在 .mli 文件中定义的模块接口时,如何让 Merlin 向我发出警告?
- jdbc - 来自 Kafka Connect 的墓碑记录
- google-chrome - 如何在 chrome 调试器中触发或触发事件?
- docker - 无法写入 docker /usr/share/logstash/config/ 中的 logstash 配置文件
- javascript - 有没有办法让 CSS 动画在动画对象不可见之前不运行?
- c# - 如何检查我的 .NET Core 控制台应用程序是作为独立应用程序运行(通过运行 myapp.exe)还是使用 dotnet myapp.dll 运行?