Skip to content

Add shared non-blocking socket tests, implement ioctl using fcntl - #5497

Merged
RalfJung merged 1 commit into
rust-lang:masterfrom
WhySoBad:udp-ioctl
Oct 30, 2026
Merged

RalfJung merged 1 commit into
rust-lang:masterfrom
WhySoBad:udp-ioctl

Conversation

@WhySoBad

Copy link
Copy Markdown
Contributor

This pull request adds ioctl(udp_sockfd, FIONBIO, ...) support to UDP sockets such that the standard library's UdpSocket::set_nonblocking method can be supported.

Additionally, the TCP socket tests which test changing the socket's blocking behavior in various ways have been moved to a shared socket-no-blocking.rs file such that they can be reused for UDP sockets.

@rustbot rustbot added the S-waiting-on-review Status: Waiting for a review to complete label Oct 26, 2026
Comment thread src/shims/unix/udp_socket.rs Outdated
Comment on lines +146 to +179
fn ioctl<'tcx>(
&self,
op: Scalar,
args: Varargs<'tcx, '_>,
ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, i32> {
assert!(ecx.machine.communicate(), "cannot have `UdpSocket` with isolation enabled!");

let fionbio = ecx.eval_libc("FIONBIO");

if op == fionbio {
// On these OSes, Rust uses the ioctl, so we trust that it is reasonable and controls
// the same internal flag as fcntl.
if !matches!(ecx.tcx.sess.target.os, Os::Linux | Os::Android | Os::MacOs | Os::FreeBsd)
{
// FIONBIO cannot be used to change the blocking mode of a socket on solarish targets:
// <https://github.com/rust-lang/rust/commit/dda5c97675b4f5b1f6fdab64606c8a1f21021b0a>
// Since there might be more targets which do weird things with this option, we use
// an allowlist instead of just denying solarish targets.
throw_unsup_format!(
"ioctl: setting FIONBIO on sockets is unsupported on target {}",
ecx.tcx.sess.target.os
);
}

let ([value_ptr], _) = ecx.check_varargs(shim_varargs![*i32], args, "ioctl")?;
let value = ecx.deref_pointer(&value_ptr)?;
let non_block = ecx.read_scalar(&value)?.to_i32()? != 0;
self.is_non_block.set(non_block);
return interp_ok(0);
}

throw_unsup_format!("ioctl: unsupported operation {op:#x} on socket");
}

@RalfJung RalfJung Oct 28, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is an exact copy of the code for TCP sockets, right?

That seems unfortunate. Would a generic implementation in terms of get_flags / set_flags make sense?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes this is a copy of the TCP socket implementation.

Would a generic implementation in terms of get_flags / set_flags make sense?

Do you mean having a set_non_blocking and get_non_blocking implementation? I think this could be confusing since we can also set/get the blocking mode through set_flags/get_flags.
However, as far as I can tell, all socket types have the same ioctl options available. Thus, we could instead have a helper in the socket.rs which handles ioctl for the different socket types (similar to how we did it with the socket options) such that we don't need to duplicate this implementation.

@RalfJung RalfJung Oct 28, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What I meant is that here we could have a case for FIONBIO that calls get_flags + set_flags on the unix FD. Then we can remove UnixFileDescription::ioctl completely I think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, this seems better. I'll change it to this.

@WhySoBad
WhySoBad force-pushed the udp-ioctl branch 2 times, most recently from 75745d1 to e93b5a5 Compare October 30, 2026 15:37
@rustbot

This comment has been minimized.

@WhySoBad WhySoBad changed the title Add ioctl support to UDP sockets, add shared non-blocking socket tests Add shared non-blocking socket tests, implement ioctl using fcntl Oct 30, 2026
@rustbot

rustbot commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@WhySoBad

WhySoBad commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

I noticed that the virtual socket shim had a check that disallowed ioctl for pipes, this now no longer works. Are we fine with allowing ioctl for pipes (assuming the tests which ensure FIONBIO behaves the same as O_NONBLOCK pass)?

@RalfJung
RalfJung added this pull request to the merge queue Oct 30, 2026
@RalfJung

Copy link
Copy Markdown
Member

If it works naively then yeah it's fine for this to also work in Miri. :)

Merged via the queue into rust-lang:master with commit 355a581 Oct 30, 2026
15 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: Waiting for a review to complete label Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants