c - 检测带有 O_NONBLOCK 的文件描述符在 FFI 场景中是否仍然有效

标签 c linux smalltalk ffi

如果我有一个已使用 open (2) 打开的文件描述符,并随后使用 fcntl (2) 设置为 O_NONBLOCK 使用FFI(外部函数接口(interface))。

这意味着几乎每次调用 read (2) 都会返回 -1,errno 设置为 EAGAIN,这意味着这次有没有可用数据。

遗憾的是,我使用的 FFI 无法访问 errno 变量,因此我无法确定返回 -1 值是因为没有数据还是因为文件句柄不再有效。

因此,我试图以某种方式确定文件描述符是否仍然有效,而无需读取 errno。我already tried all the answers with fcntl from this question ,但它们不起作用并且永远不会返回 -1。

也许这是因为我正在读取设备文件:/dev/input/js0

我可以调用另一个函数来告诉我文件描述符是否无效吗? (在上面的问题中有人提到了民意调查,但我不确定这是什么意思。)

我正在使用 Squeak FFI,并且不允许添加任何自定义 C 包装器。我正在尝试访问游戏 handle 并从中读取按钮信息,这是一项可选任务。

我用 fcntl 尝试过的 Smalltalk 源代码:

fcntl 的 FFI(在类 Gamepad 中定义):

manipulateFileHandle: fileHandle command: command
    < cdecl: long 'fcntl' ( long long ) module: 'libc.so.6' >
    ^ self externalCallFailed

然后在另一种方法中,我称之为:

| handleTest |
handleTest := Gamepad manipulateFileHandle: externalFileHandle command: 1.
Transcript show: handleTest; cr.

命令 1 是 F_GETFD,读取文件描述符标志。但 handleTest 永远不会是 -1,即使拔掉游戏 handle 后也是如此。

最佳答案

在 GNU/Linux 系统上,libc 包含函数 __errno_location(),该函数返回 errno 变量的地址。您的 FFI 应该能够调用该函数,然后取消引用表示 int * 的地址。

在 GCC 发明线程局部变量语法之前,允许多线程代码安全操作 errno 的技术是将其定义为:

#define errno (*__errno_location ())

该函数将返回线程本地地址。在 Linux 系统上,如果您对使用 errno 的 C 代码使用 gcc -E,您将看到扩展。

As explained by Barmar, the fcntl() techniques work. The reason it never returned -1 was because you were still holding a valid file descriptor. A file descriptor does not become invalid until it is closed.

关于c - 检测带有 O_NONBLOCK 的文件描述符在 FFI 场景中是否仍然有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37061993/

相关文章:

parsing - 使用smalltalk编写一个小解析器,如何使用创建的方法'标识符?

c - 将 xml 值映射到结构体值

c - C 将字符输入数组时出现段错误

c# - 在 mod_mono (3.12.1) 上运行的 XHR 代理中的 System.Threading.ThreadAbortException

linux - Bash 中的简单套接字服务器?

ide - 什么是学习 smalltalk 的最佳免费 IDE?

smalltalk - Smalltalk 中重复的组合

c - MSP430 UART 与 Raspberry Pi 的不需要的环回

c - 如何让我的程序在没有警告的情况下编译?

c++ - SystemC:对端口的 read() 和 write() 不起作用