为啥 Linux Open 系统调用不需要路径的缓冲区大小参数?

Posted

技术标签:

【中文标题】为啥 Linux Open 系统调用不需要路径的缓冲区大小参数?【英文标题】:Why does the Linux Open system call not need a buffer size parameter for the path?为什么 Linux Open 系统调用不需要路径的缓冲区大小参数? 【发布时间】:2019-08-11 05:48:35 【问题描述】:

为什么open 系统调用不需要像write 系统调用那样的缓冲区大小参数?

这两个系统调用如何区别对待它们的字符串参数?

open 系统调用是否假定路径参数以零结尾的字符串,而 write 系统调用不假定?如果是,为什么不一致?

为什么不让所有(或不)使用字符串/数组的系统调用都需要大小参数?

【问题讨论】:

这是一个正常的以 0 结尾的字符串,是的,而 write() 可用于不是的数据。 open 需要一个以零结尾的文件名(零字节在文件名中无效)。 write 写入 二进制 数据,因此可能会出现零字节,因此不能用作缓冲区终止符 【参考方案1】:

UNIX 最初是作为一种用于汇编程序编写的操作系统,后来用于用 C 编写的程序。在 UNIX 团队使用的汇编约定以及后来的 C 语言中,字符串以 NUL 字节结束。因此,在与操作系统对话时使用相同的约定是很自然的。 Linus 在设计 Linux 时复制了 UNIX API,这就是为什么它具有相同的设计。使用 NUL 终止字符串不会丢失任何功能,因为 NUL 字节不允许出现在路径或其他标识符中。

write 调用将任意二进制数据写入文件。该数据不一定是文本,因此使用字符串约定没有多大意义。

【讨论】:

` 使用 NUL 终止字符串不会丢失任何功能,因为 NUL 字节不允许出现在路径或其他标识符中。`好吧,这正是功能丢失 - 因为字符串以空值结尾,Unix 不会'不允许标识符中有空字节。虽然我不认为这是一个很大的损失,而且我知道没有操作系统允许这样做,但正式地,你的陈述在内部是矛盾的。 哈!用于二进制数据而不是字符串的写入是我误解的根源。到目前为止,每次我使用 write 系统调用时,我都是使用字符串参数来完成的,所以我没有考虑过您可能想要使用 write 系统调用来写入在字符串中实际上没有意义的字节,例如作为NULL。当我将它视为 write 不是字符串的缓冲区参数时,它开始变得有意义。谢谢。 @SergeyA 没有矛盾;如果有人要创建一个 UNIX 变体,其中路径作为缓冲区/长度对传递,您仍然不能创建名称包含 NUL 字节的文件,因为这是 POSIX 标准所禁止的。 @fuz 不过,这有点循环推理。现在 POSIX 标准的很多内容实际上只是对早期 Unix 变体中的工作方式的编纂。 @AndrewHenle 您是从“如果当初做出不同的设计决策,我们可以拥有更多功能”的角度来看这一点,而我认为这是“今天改变界面不会提供更多功能” 。”这两个立场都是正确的,但我认为考虑在这种情况下可能会发生什么是没有用的。

以上是关于为啥 Linux Open 系统调用不需要路径的缓冲区大小参数?的主要内容,如果未能解决你的问题,请参考以下文章

系统调用open的大概执行路径

linux为啥总是找不到java命令

linux系统要运行一个程序为啥必须程序在当前目录下

在调用一些Python里的函数的时候 为啥有些函数需要实例化有些不需要?

Linux Kernel 4.2.x:为啥检查时预期的系统调用地址与实际地址不匹配?

creat open 系统调用