Skip to content

Support F_GETFL and F_SETFL for fcntl #4212

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open

Conversation

tiif
Copy link
Contributor

@tiif tiif commented Feb 26, 2025

This PR supports F_SETFL and F_GETFL flags for fcntl. In this implementation, F_SETFL can only set O_NONBLOCK flag.

If setfl is called while a fd is blocking, that fd will not be affected by the new flag value and will continue blocking like normal until a read/write wakes it up (it acts like it never knew the setfl has happened). But any operation after setfl will see the new flag value.

The interaction between these fcntl operations and blocking fd is summarised here.

Fixes #4119

Copy link
Contributor Author

@tiif tiif left a comment

Choose a reason for hiding this comment

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

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Waiting for a review to complete labels Feb 26, 2025
Copy link
Member

@RalfJung RalfJung left a comment

Choose a reason for hiding this comment

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

Here's the first round of comments. Sorry for the long wait!

@rustbot author

Comment on lines 215 to 219
if flag == this.eval_libc_i32("O_NONBLOCK") {
anonsocket_fd.set_nonblock();
} else {
throw_unsup_format!("fcntl: only O_NONBLOCK are supported for F_GETFL")
}
Copy link
Member

Choose a reason for hiding this comment

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

This should also support un-setting the O_NONBLOCK flag, right? I assume that's what happens on flag == 0.

Copy link
Contributor Author

@tiif tiif Apr 12, 2025

Choose a reason for hiding this comment

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

Good call!

I just realised this is indeed how tokio set their fd from non-blocking to blocking. https://github.com/tokio-rs/tokio/blob/817fa605ee6a2549fe8e6057ec23a8309d42d2e9/tokio/src/net/unix/pipe.rs#L1432

@rustbot rustbot removed the S-waiting-on-review Status: Waiting for a review to complete label Apr 9, 2025
@rustbot
Copy link
Collaborator

rustbot commented Apr 9, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: Waiting for the PR author to address review comments label Apr 9, 2025
@tiif
Copy link
Contributor Author

tiif commented Apr 12, 2025

On the latest commit b22019d, I made all the tests in this PR to use isolation mode.

err_unsup_format!("fcntl: only socketpair / pipe are supported for F_GETFL")
})?;

if anonsocket_fd.is_nonblock() {
Copy link
Member

Choose a reason for hiding this comment

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

Does this match real implementations -- only returning O_NONBLOCK and no other flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I overlooked something, we need to return O_RDWR for socketpair, O_RDONLY and O_WRONLY for pipe. So we need to add something to differentiate between socketpair and pipe's reading / writing end here.

Copy link
Member

Choose a reason for hiding this comment

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

Probably we should have get_flags and set_flags methods on the FD trait so this logic can live with the FD implementation.

When a socketpair's peer FD has been closed, does it become RDONLY?

Copy link
Contributor Author

@tiif tiif Apr 20, 2025

Choose a reason for hiding this comment

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

When a socketpair's peer FD has been closed, does it become RDONLY?

fcntl(F_GETFL) will still return O_RDWR even though the subsequent write will error with EPIPE.

Same thing happened to pipe too. So both socketpair and pipe fds have fixed O_RDONLY / O_WRONLY / O_RDWR value.

Copy link
Member

Choose a reason for hiding this comment

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

Okay, then please implement that and add a comment explaining why.

@tiif
Copy link
Contributor Author

tiif commented Apr 22, 2025

Just a heads up, this PR will stall for a while due to exam prep, but I will be back on it after rust week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: Waiting for the PR author to address review comments
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support F_SETFL and F_GETFL
3 participants