Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-112341: Specify the exact file size if offset is non zero insocket.sendfile#112342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
aisk wants to merge4 commits intopython:mainfromaisk:fix-blocksize-in-sendfile

Conversation

aisk
Copy link
Contributor

@aiskaisk commentedNov 23, 2023
edited by bedevere-appbot
Loading

I think this is a minor fix, so the news entry is not needed.

@erlend-aaslanderlend-aasland changed the titlegh-112341: specify the exact filesize if offset is non zero in socket.sendfilegh-112341: Specify the exact file size if offset is non zero insocket.sendfileJan 6, 2024
@erlend-aasland
Copy link
Contributor

Is there an easy way to add tests for this?

@aisk
Copy link
ContributorAuthor

Thanks for the review, test case added.

@erlend-aasland
Copy link
Contributor

How does this relate toos.sendfile? Willos.sendfile andsocket.sendfile have divergent behaviour? OTOH, how is their behaviour now?

@aisk
Copy link
ContributorAuthor

os.sendfile is just a wrapper function which almost directly calls the syscall functionsendfile. Thesendfile is just like thewrite, it may not send all the data you give to it.

socket.sendfile is build uponos.sendfile, which will ensure all the data will be written. To get this, it may invokeos.sendfile multiple times.

The problem this PR want to resolve is that, if we have a file with size 42, and want to send it to a socket from the start2, we will invoke it likes.sendfile(f, offset=2, count=None).

Because we do not specify the count parameter,socket.sendfile will assume that we want send the whole file from the offset. So the count should befsize - offset, which is42 - 2 = 40. And the count is << 1G (max block size), so we will use count as block size.

The current codes in main branch missed the - offset, so it will use 42 asblocksize.

Thensocket.sendfile will invokeos.sendfile(in_fd, out_fd, offset=2, count=42). So we give the syscallsendfile a valid range, which it's end is out of the file.

Modern systems which CPython supports withsendfile feature will accept it, and only returns the actually sent bytes (is 40 in this case). So nothing goes wrong here.

But I've tried to implement theos.sendfile via Windows'sTransmitFile, and found thatTransmitFile don't accept the out of range count argument. (Meanwhile, it accepts theoffset is out of range to the file).

So I think this is a bug and we should fix it.

But, the is not the end of this story. I found that theTransmitFile have much more different behaviors to the Unix'ssendfile, the main block is thatTransmitFile does not respect theSO_SNDTIMEO option to make a timeout. Then I give up it, and just try to implement the high levelsocket.sendfile viaTransmitFile. This PR is opened as#112337.

And then the change in this PR is not a must to have. But I still feels like it's a bug, so we should fix it 😂.

erlend-aasland reacted with thumbs up emoji

@erlend-aasland
Copy link
Contributor

Thanks,@aisk, makes sense to me! cc.@serhiy-storchaka if he want's to take a look. I'm aiming for landing this in a couple of days.

@erlend-aaslanderlend-aasland self-assigned thisJan 14, 2024
@erlend-aasland
Copy link
Contributor

Could you try to compose a short NEWS entry for this? I'm unsure if we really need one; this feels like an implementation detail.

@@ -360,7 +360,7 @@ def _sendfile_use_sendfile(self, file, offset=0, count=None):
if not fsize:
return 0 # empty file
# Truncate to 1GiB to avoid OverflowError, see bpo-38319.
blocksize = min(count or fsize, 2 ** 30)
blocksize = min(count or fsize - offset, 2 ** 30)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What ifoffset >= fsize?

Please add tests foroffset == fsize andoffset > fsize.

@erlend-aasland
Copy link
Contributor

See also#114077 and#114079.

@aisk
Copy link
ContributorAuthor

There are some discussions on the original issue#112341. I think this should not be treated as a bug, so I'm closing this. If anyone wants to discuss it further, we can reopen it. Still appreciate the review!

@aiskaisk closed thisJan 25, 2024
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@serhiy-storchakaserhiy-storchakaserhiy-storchaka left review comments

Assignees

@erlend-aaslanderlend-aasland

Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

3 participants
@aisk@erlend-aasland@serhiy-storchaka

[8]ページ先頭

©2009-2025 Movatter.jp