【问题标题】:write system call, what's the number of bytes limit?写系统调用,字节数限制是多少?
【发布时间】:2012-09-13 22:43:41
【问题描述】:

写入系统调用原型为:

ssize_t write(int fd, const void *buf, size_t count);

count参数是无符号的,返回值是有符号的。

帮助页面显示:

成功时,返回写入的字节数(零表示未写入任何内容)。 出错时返回-1,并适当设置errno

但是,它并没有说明 count 参数的限制是多少。 当计数大于SSIZE_MAX 时,它仍然没有说明行为。

考虑到 write 是一个可用于通用设备/文件/任何东西的系统调用,如果设备支持大于 SSIZE_MAX 的写入操作,则返回类型无法处理实际写入的字节数。

传递无符号字节数并返回有符号字节数对我来说没有意义。为什么不直接传递一个签名号码?

感觉就像 write 函数的原型有点容易出错,或者至少它在路径中留下了一个可能的漏洞。

有没有人知道它的详细信息或者我在哪里可以找到这些信息?

【问题讨论】:

  • 我自己不知道,但我相信限制是无符号整数的大小。这意味着,您应该能够一次写入 4294967296 个字节。在这种情况下,返回值为 -1(您必须检查 errno 以确保它实际上是一个错误)
  • POSIX says "如果 nbyte 的值大于 {SSIZE_MAX},则结果是实现定义的",因此缺少 Linux 手册页 -- 它应该描述这一点。
  • 习惯上 write() 使用较小的块。我很难想象用单个系统调用写入千兆字节的情况是个好主意。
  • 我不想写一大堆数据。问题是我正在编写一个平台抽象层,我需要为这个函数创建一个包装器。我将它用于套接字。我想了解与这种情况相关的问题。
  • @Marcus:对于套接字,您的限制可能远低于SSIZE_MAX,并且与ioctl 和/或setsockopt 在套接字上配置的缓冲区大小相关。

标签: c linux types


【解决方案1】:

谷歌搜索:

如果nbyte的值大于 {SSIZE_MAX},结果是实现定义的。

来源:http://pubs.opengroup.org/onlinepubs/009695399/functions/write.html

【讨论】:

  • 我知道这是实现定义的(如上面大多数帖子中所述)。但是,我找不到为特定实现解释该行为的一个地方。我相信“实现”是指设备/文件系统/任何实现。您知道观察到这种情况的地方吗?
  • 实现意味着编写该函数的人。可能是您的编译器提供商或操作系统提供商。检查编译器或操作系统的文档。由于您标记了 linux,它可能是带有 GNU C 库的 GCC。不幸的是,它的文档gnu.org/software/libc/manual/html_node/… 没有指定实现定义的行为(可能想要在文档中提交错误报告)。除非你(和很多人一样)相信“代码就是文档”,在这种情况下,只需查看代码(这是开源的全部意义所在)。
  • 我可能会提交错误报告。谢谢。
【解决方案2】:

我认为没有硬性限制,这取决于fd 指向的内容。例如,如果它是文件系统上的文件,那么如果您超过“最大文件大小限制”,文件系统驱动程序将阻塞,返回 EFBIG 错误:

EFBIG 试图写入超出实现范围的文件- 定义的最大文件大小或进程文件大小限制。

【讨论】:

  • 对,该参数只是传递给特定设备的实现。
  • 如果fd 指代一个套接字(通常是非阻塞的),则可能会得到ENOMEM
  • 我并不十分担心套接字的情况。要点是:如果设备支持大于 SSIZE_MAX 的写入操作,则返回类型无法处理实际写入的字节数。感觉就像 write 函数的原型有点容易出错,或者至少它在路径上留下了一个可能的漏洞。
  • @Marcus - 在什么系统上,您可以实际分配大于SSIZE_MAX 的缓冲区?我相信可用的内存是有限的,而不是设备。
  • @Bo Persson - 这不是能够这样做的问题。关键是功能界面很奇怪。它说它会返回写入的字节数,但它不能真正做到这一点。有一个很大的“但是”被描述为“依赖于实现”。但是我找不到任何关于 linux 实现的信息。
【解决方案3】:

我想记住系统分配给函数的字节数。但我不确定。也许你应该试试 size_t 和 ssize_t 手册页。

【讨论】:

  • 我弄错了,在include文件夹中有,但我不知道它在哪一个=S希望你能找到它!
  • 别担心!谢谢你的帮助。 :D
猜你喜欢
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
相关资源
最近更新 更多