美文网首页
linux手册翻译——sendfile(2)

linux手册翻译——sendfile(2)

作者: 蟹蟹宁 | 来源:发表于2021-07-02 08:38 被阅读0次

    \color{#A00000}{NAME}
    sendfile - transfer data between file descriptors

    \color{#A00000}{SYNOPSIS}

    #include <sys/sendfile.h>
    
    ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
    

    \color{#A00000}{DESCRIPTION}
    sendfile() 在一个文件描述符和另一个文件描述符之间复制数据。 因为这种复制是在内核中完成的,所以 sendfile() 比 read(2) 和 write(2) 的组合更有效,后者需要将数据传入和传出用户空间。

    in_fd 是一个为读取而打开的文件描述符,out_fd 是一个为写入而打开的描述符。

    如果 offset 不为NULL,则sendfile()将以其为偏移量从in_fd中读取数据。当 sendfile() 返回时,此变量将设置为读取的最后一个字节之后的偏移量。 如果 offset 为 NULL,则将从 in_fd 中的文件偏移量开始读取数据。

    需要注意!如果指定了offset,那么读取 in_fd中的数据是不会修改其打开文件自身的偏移量的。

    count 是要在文件描述符之间复制的字节数。

    in_fd 参数必须是支持类似 mmap(2) 等操作的文件(即它不能是套接字)。

    在 2.6.33 之前的 Linux 内核中,out_fd 必须引用套接字。 从 Linux 2.6.33 开始,它可以是任何文件。 如果它是一个常规文件,则 sendfile() 适当地更改out_fd的文件偏移量。

    \color{#A00000}{RETURN VALUE}
    如果传输成功,则返回写入 out_fd 的字节数。 请注意,成功调用 sendfile() 可能会写入比请求更少的字节; 如果有未发送的字节,调用者应该准备重试调用。 另见NOTES。
    出错时,返回 -1,并设置 errno 以指示错误。

    \color{#A00000}{ERRORS}

    • EAGAIN
      Nonblocking I/O has been selected using O_NONBLOCK and the write would block.

    • EBADF
      输入文件或输出文件未打开。

    • EFAULT
      Bad address.

    • EINVAL
      描述符无效或被锁定,或者类似 mmap(2) 的操作对 in_fd 不可用,或者计数为负数。

    • EINVAL
      out_fd 设置了 O_APPEND 标志。 sendfile() 当前不支持此功能。

    • EIO
      从 in_fd 读取时出现未指定的错误。

    • ENOMEM
      Insufficient memory to read from in_fd.

    • EOVERFLOW
      计数太大,操作将导致超过输入文件或输出文件的最大大小。

    • ESPIPE
      offset 不是 NULL 但输入文件is not seekable.

    \color{#A00000}{VERSIONS}
    sendfile() 首次出现在 Linux 2.2 中。 从 glibc 2.1 开始就存在包含文件 <sys/sendfile.h>。

    \color{#A00000}{CONFORMING TO}
    Not specified in POSIX.1-2001, nor in other standards.

    Other UNIX systems implement sendfile() with different semantics and prototypes. It should not be used in portable programs.

    \color{#A00000}{NOTES}
    sendfile() 最多传输 0x7ffff000 (2,147,479,552) 个字节,返回的是实际传输的字节数。 (在 32 位和 64 位系统上都是如此。)

    如果您计划使用 sendfile() 将文件发送到 TCP 套接字,但需要在文件内容之前发送一些标头数据,您会发现使用 TCP_CORK 选项很有用,在 tcp(7) 中描述,以最小化 数据包的数量并调整性能。

    根据tcp(7),TCP_CORK的作用是:如果设置,则不发送部分帧。 当再次清除该选项时,将发送所有排队的部分帧。更方便的,可以在执行时send()时设置MSG_MORE标志,见send(2)

    在 Linux 2.4 及更早版本中,out_fd 也可以指普通文件; 这种可能性在 Linux 2.6.x 内核系列中消失了,但在 Linux 2.6.33 中恢复了。

    最初的 Linux sendfile() 系统调用不是为了处理大文件偏移量而设计的。 因此,Linux 2.4 添加了 sendfile64(),偏移参数的类型更宽。 glibc sendfile() 包装函数透明地处理内核差异。

    在 sendfile() 因 EINVAL 或 ENOSYS 失败的情况下,应用程序可以回退到 read(2)/write(2)。

    如果 out_fd 引用了具有零拷贝支持的套接字或管道,则调用者必须确保 in_fd 引用的文件的传输部分保持不变,直到 out_fd 另一端的读取器消耗了传输的数据。

    Linux 特定的 splice(2) 调用支持在任意文件描述符之间传输数据,前提是其中一个(或两个)是管道。

    相关文章

      网友评论

          本文标题:linux手册翻译——sendfile(2)

          本文链接:https://www.haomeiwen.com/subject/impsultx.html