在ioctl中打开有什么不良副作用?

Car*_*guz 6 c unix linux posix ioctl

根据man ioctl,打开文件描述符open可能会导致不必要的副作用.该手册还指出开头O_NONBLOCK解决了那些不必要的问题,但我似乎无法找到原因,也不知道实际的副作用是什么.有人可以解释一下吗?随着ioctl它总是可能和等效*打开文件描述符O_NONBLOCK

注释(来自man ioctl)

为了使用此调用,需要一个打开的文件描述符.通常open(2)调用会产生不必要的副作用,这可以通过给它O_NONBLOCK标志在Linux下避免.

(*我知道这O_NONBLOCK意味着什么,但我不知道这是否影响ioctl调用它会影响其他系统调用.我的程序,用于ioctl从SPI总线写入和读取,与启用该标志完美配合.)

Ilm*_*nen 7

寻找答案的显而易见的地方是open(2)手册页,其标题为O_NONBLOCK:

如果可能,文件以非阻塞模式打开.对返回的文件描述符的open()或任何后续操作都不会导致调用进程等待.

[...]

有关FIFO(命名管道)的处理,另请参见fifo(7).有关O_NONBLOCK结合强制文件锁和文件租约的影响的讨论,请参阅fcntl(2).

好的,这不是很有用,但让我们按照链接查看fifo(7)和fcntl(2)的手册页说:

通常,打开FIFO块直到另一端打开.

进程可以在非阻塞模式下打开FIFO.在这种情况下,即使在写入端尚未打开任何人,只读打开也会成功,并且只读打开将因ENXIO(没有这样的设备或地址)而失败,除非另一端已经打开.

在Linux下,打开FIFO进行读写将在阻塞和非阻塞模式下成功.POSIX未定义此行为.

所以这里至少有一个"不必要的副作用":即使只是试图打开一个FIFO也可能会阻塞,除非你O_NONBLOCK转到open()呼叫(并打开它进行读取).

那么fcntl呢?正如open(2)手册页所述,要查看的部分是"强制锁定"和"文件租约".这似乎对我来说,强制锁,在这种情况下,是一个红色的鲱鱼,虽然-他们只导致阻塞当一个人试图从实际读取或写入文件:

如果进程尝试对具有不兼容的强制锁定的文件区域执行不兼容的访问(例如,read(2)或write(2)),则结果取决于是否为其打开的文件描述启用了O_NONBLOCK标志.如果未启用O_NONBLOCK标志,则系统调用将被阻止,直到锁定被删除或转换为与访问兼容的模式.

那么租约怎么样?

当进程("租用断路器")执行open(2)或truncate(2)与通过F_SETLEASE建立的租约冲突时,系统调用被内核阻止,内核通过发送信号通知租约持有者(默认情况下为SIGIO).[...]

一旦租约被自愿或强行删除或降级,并且假设租约破坏者未解锁其系统调用,内核允许租用断路器的系统调用继续进行.

[...]如果租用断路器在调用open(2)时指定O_NONBLOCK标志,则调用会立即失败,并显示错误EWOULDBLOCK,但其他步骤仍然如上所述发生.

好的,这是另一个不必要的副作用:如果您尝试打开的文件有租约,则open()调用可能会阻止,直到租赁持有人已经释放租约.

在这两种情况下,"不良副作用"所传递避免O_NONBLOCKopen()是勿庸置疑,在open()调用本身阻塞,直到其他进程所做的事.如果您引用的手册页中有任何其他类型的副作用,我不知道它们.