C 检测具有O_非块的文件描述符在FFI场景中是否仍然有效
如果我有一个文件描述符,该描述符已使用C 检测具有O_非块的文件描述符在FFI场景中是否仍然有效,c,linux,smalltalk,ffi,C,Linux,Smalltalk,Ffi,如果我有一个文件描述符,该描述符已使用open(2)打开,随后使用fcntl(2)使用FFI(外部功能接口)设置为O\u NONBLOCK 这意味着几乎所有对read(2)的调用都将返回-1,errno设置为EAGAIN,这意味着这次没有可用的数据 遗憾的是,我使用的FFI无法访问errno变量,因此我无法确定是否返回了-1值,因为没有数据或文件句柄不再有效 因此,我试图以某种方式确定文件描述符是否仍然有效,而无需读取errno。我知道,但他们不工作,永远不会回来 也许这是因为我正在读取一个设备
open(2)
打开,随后使用fcntl(2)
使用FFI(外部功能接口)设置为O\u NONBLOCK
这意味着几乎所有对read(2)
的调用都将返回-1,errno
设置为EAGAIN
,这意味着这次没有可用的数据
遗憾的是,我使用的FFI无法访问errno
变量,因此我无法确定是否返回了-1值,因为没有数据或文件句柄不再有效
因此,我试图以某种方式确定文件描述符是否仍然有效,而无需读取errno
。我知道,但他们不工作,永远不会回来
也许这是因为我正在读取一个设备文件:/dev/input/js0
我是否可以调用另一个函数来告诉我文件描述符是否无效?(在上面的问题中,有人提到了投票,但我不知道这是什么意思。)
我使用Squeak FFI,不允许添加任何自定义C包装。我正在尝试访问游戏板并从中读取按钮信息,这是一项可选任务
Smalltalk是我使用fcntl尝试的源代码:
fcntl
的FFI(在类Gamepad
中定义):
命令
1是读取文件描述符标志的F_GETFD
。但是handleTest
永远不会是-1,即使在拔下游戏板之后也是如此。在GNU/Linux系统上,libc
包含函数\u errno\u location()
,该函数返回errno
变量的地址。您的FFI应该能够调用该函数,然后取消引用表示int*
的地址
在GCC发明线程局部变量语法之前,允许多线程代码安全操作errno
的技术是将其定义为:
#define errno (*__errno_location ())
该函数将返回一个线程本地地址。在Linux系统上,如果在使用errno
的C代码上使用gcc-E
,您将看到扩展
正如Barmar所解释的,fcntl()
技术可以工作。它从未返回-1
的原因是您仍然持有有效的文件描述符。文件描述符在关闭之前不会变为无效。
你不允许写任何C代码吗?请在问题中具体说明这些限制。要通过反复审问你来发现所有难以言喻的限制是很糟糕的。你在用什么系统?你可以写不可移植的代码吗?因为大多数libc实现都有一个返回指向
errno
的指针的函数。你能提供一个说明性的程序来说明你尝试了什么,这样我们就可以看到你引入的错误是否导致它不起作用了?你的fcntl
想法应该是可行的。FD关闭后,它最初在什么类型的设备上打开并不重要。您能否在smalltalk代码中取消引用int*
?函数\u errno\u location()
将返回errno
变量的地址。@NikonthThird拔下设备不会使FD无效。FD不会失效,除非您对其调用close()
。非常感谢。\u errno\u位置
调用正常,现在我可以访问errno
。对于任何有相同问题的人:必须在Squeak中定义一个从ExternalStructure
派生的单独类,否则最终将得到一个不透明的ExternalData
指针。字段:fields^#((errno'long'))
,FFI调用:
| handleTest |
handleTest := Gamepad manipulateFileHandle: externalFileHandle command: 1.
Transcript show: handleTest; cr.
#define errno (*__errno_location ())