如果我有一个用open (2)
打开的文件描述符,然后使用FFI(外部函数接口)使用O_NONBLOCK
设置为fcntl (2)
。
这意味着几乎每次调用read (2)
都会返回-1,errno
设置为EAGAIN
,这意味着此时没有数据可用。
可悲的是,我使用的FFI无法访问errno
变量,因此我无法确定是否返回-1值,因为没有数据或文件句柄不再有效。
所以我试图以某种方式确定文件描述符是否仍然有效而无需阅读errno
。我already tried all the answers with fcntl
from this question,但他们不工作,永远不会返回-1。
也许这是因为我正在阅读设备文件:/dev/input/js0
?
我可以调用另一个函数来告诉我文件描述符是否无效? (在上面的问题中有人提到poll
,但我不确定这是什么意思。)
我正在使用Squeak FFI,不允许添加任何自定义C包装器。我正在尝试访问游戏手柄并从中读取按钮信息,这是一个可选的任务。
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.
command
1是F_GETFD
,读取文件描述符标志。但即使拔掉游戏手柄,handleTest
也永远不会是-1。
答案 0 :(得分:3)
在GNU / Linux系统上,libc
包含函数__errno_location()
,它返回errno
变量的地址。您的FFI应该能够调用该函数,然后取消引用代表int *
的地址。
在GCC发明线程局部变量的语法之前,允许多线程代码安全地操作errno
的技术是将其定义为:
#define errno (*__errno_location ())
该函数将返回一个线程本地地址。在您的Linux系统上,如果您对使用gcc -E
的C代码使用errno
,您将看到扩展。
正如Barmar所解释的那样,
fcntl()
技术起作用。它永远不会返回-1
的原因是因为您仍然持有有效的文件描述符。文件描述符在关闭之前不会变为无效。 子>