如果我有一个已使用 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/