Skip to content

inaccurate block size in socket._sendfile_use_sendfile #112341

Closed as not planned
Closed as not planned

Description

@aisk

Bug report

Bug description:

socket._sendfile_use_sendfile(self, file, offset=0, count=None) intent to use the file size reamains from current position as block size, to a underlying sendfile syscall, when count is not specified.

But as the codes below shows, it will always use the whole file size as block size even if offset is non zero, so the blocksize is larger than actuall file bytes remains from offset:

blocksize = min(count or fsize, 2 ** 30)

On modern platforms, if someone specified the count which is larger than the actual file size, sendfile will accept it, and only sending the remaining data and returns the bytes which have been sent.

So the bug (if it is a bug) have no effect for now, and it's so minor, but I think we should fix it however. And if we want using TransmitFile as a sendfile implenentation on Windows, the inaccurate block size will leads to an error, which is mentioned in #102898 (comment), and the fix will be a must have.

CPython versions tested on:

3.8, 3.9, 3.10, 3.11, 3.12, 3.13, CPython main branch

Operating systems tested on:

macOS

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Nov 23, 2023
  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Nov 26, 2023
  3. serhiy-storchaka commented on Jan 15, 2024

    @serhiy-storchaka
    Member

    I do not think that there is a bug.

    Note that os.sendfile() can send less than the specified amount of bytes. So it is used in loop unless it returns 0. But blocksize is not changed in the loop if count is false (which means "send to the end of the file"), so the second and the following calls of sendfile() are with the amount of bytes that exceed the number of bytes that left. If there is an issue with this, it requires more complex solution. But I think that it works correctly.

    It seems that if count is false, socket.sendfile() can send a file whose size is increased between calls of os.sendfile(). It may be a feature.

  4. aisk commented on Jan 15, 2024

    @aisk
    MemberAuthor

    I got the point, in the second iteration of the loop in socket.sendfile will also call the os.sendfile with the blocksize at the position out the fsize.

    I don't know if the increase size between loop is a feature. But if we fix it by caculate the blocksize in every iteration, Since current platforms CPython support, their sendfile syscall accepts the larger blocksize, so treat it as a bug and introduce some complexity is pointless.

    Thanks for the review and point this out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions