Skip to content

Implement recv and send for virtual sockets#5161

Merged
RalfJung merged 1 commit into
rust-lang:masterfrom
WhySoBad:virtual-socket-trait-impl
Jul 8, 2026
Merged

Implement recv and send for virtual sockets#5161
RalfJung merged 1 commit into
rust-lang:masterfrom
WhySoBad:virtual-socket-trait-impl

Conversation

@WhySoBad

@WhySoBad WhySoBad commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

This pull request adds a basic implementation for recv and send from UnixSocketFileDescription for the virtual socket shim.
Additionally, it also adds support for non-blocking read/write operations to virtual sockets.

I didn't add support for peeking as this isn't as straightforward with VecDeques as I had hoped it was. We would need to manually use copy_from_slice on the front slice returned from as_slices. Instead, I'm considering opening a PR on the standard library to add a peek implementation there -- however, I'm not sure whether this is enough of an use-cse to be part of the standard library.

Also, is there a reason why the buffer is implemented using a VecDeque instead of just using a Vec? I couldn't find where the queue property was needed.

Close #4958

@rustbot rustbot added the S-waiting-on-review Status: Waiting for a review to complete label Jul 5, 2026
@RalfJung

RalfJung commented Jul 8, 2026

Copy link
Copy Markdown
Member

Also, is there a reason why the buffer is implemented using a VecDeque instead of just using a Vec? I couldn't find where the queue property was needed.

It's naturally a queue, isn't it? Sending adds data on one end, receiving takes data from the other end.

Let's leave peek to a future PR. But it's exposed by std so it is on the extended TODO list.

@RalfJung RalfJung left a comment

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.

Comment thread src/shims/unix/virtual_socket.rs Outdated
match self.fd_type {
VirtualSocketType::Socketpair => self,
VirtualSocketType::PipeRead | VirtualSocketType::PipeWrite =>
panic!("pipe is not a socket file description"),

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.

So... if someone does send/recv on a pipe Miri will ICE? That doesn't sound good?

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.

I've now changed the signature of as_socket to return an option. When a Unix file description isn't a socket, None is returned (in the default impl), and every method like bind, connect, etc. then returns ENOTSOCK.

Comment thread tests/pass/shims/socketpair.rs Outdated
Os::Linux | Os::Android | Os::FreeBsd | Os::Solaris | Os::Illumos
) {
// SOCK_NONBLOCK and SOCK_CLOEXEC only exist on Linux, Android, FreeBSD,
// Solaris, and Illumos targets.

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.

We don't have any libc API test that actually uses SOCK_NONBLOCK, do we?

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.

True, I've also noticed that the standard library UnixStream::set_nonblocking uses ioctl for changing the blocking mode. Since both implementations share the same underlying Socket in the standard library, I've just taken the ioctl implementation from the TCP sockets and added it for the virtual sockets as well (pipes aren't supported because I couldn't find any documentation about that).

Additionally, there are now tests for non-blocking socketpairs. There I also took the TCP socket tests and just adjusted them for socketpairs (meaning we no longer need to connect and accept, but fds[0] is the "client" socket and fds[1] is the peer socket on the "server").

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.

For reviewing, it's probably the easiest to compare the non-blocking socketpair tests to the non-blocking socket tests:
git diff virtual-socket-trait-impl:tests/pass-dep/libc/libc-socket-no-blocking.rs virtual-socket-trait-impl:tests/pass-dep/libc/libc-socketpair-no-blocking.rs

@rustbot rustbot added S-waiting-on-author Status: Waiting for the PR author to address review comments and removed S-waiting-on-review Status: Waiting for a review to complete labels Jul 8, 2026
@rustbot

rustbot commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

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

@WhySoBad

WhySoBad commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Waiting for a review to complete and removed S-waiting-on-author Status: Waiting for the PR author to address review comments labels Jul 8, 2026

@RalfJung RalfJung left a comment

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.

That's an unfortunate amount of code duplication between the socket and socketpair tests... but it's probably not worth building the infrastructure to avoid that, certainly not in this PR. (Even within those tests there's a bunch of duplication due to different ways of making a socket non-blocking, and write vs send.)

@rustbot author

View changes since this review

Comment thread tests/pass-dep/libc/libc-socketpair-no-blocking.rs Outdated
Comment thread tests/pass-dep/libc/libc-socketpair-no-blocking.rs
Comment thread tests/pass-dep/libc/libc-socketpair-no-blocking.rs Outdated
Comment thread tests/pass-dep/libc/libc-socketpair-no-blocking.rs Outdated
Comment thread tests/pass-dep/libc/libc-socketpair-no-blocking.rs Outdated
@rustbot rustbot added S-waiting-on-author Status: Waiting for the PR author to address review comments and removed S-waiting-on-review Status: Waiting for a review to complete labels Jul 8, 2026
@RalfJung

RalfJung commented Jul 8, 2026

Copy link
Copy Markdown
Member

This looks great, thanks! Please squash the commits. You can squash manually if there are multiple independent commits you want to preserve, or use ./miri squash (make sure to pick a suitable commit message). Then write @rustbot ready after you force-pushed the squashed PR.

@rustbot author

Addtionally, also add tests for non-blocking virtual sockets.
@WhySoBad WhySoBad force-pushed the virtual-socket-trait-impl branch from 2c4a123 to 944bbc6 Compare July 8, 2026 18:28
@WhySoBad

WhySoBad commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Yes I also noticed the code duplication. I think ideally there should be another libc-socket-stream test (and libc-socket-stream-no-blocking) where we test those properties of stream oriented sockets. Whether those are TCP or Unix domain sockets shouldn't matter then.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Waiting for a review to complete and removed S-waiting-on-author Status: Waiting for the PR author to address review comments labels Jul 8, 2026
@RalfJung RalfJung enabled auto-merge July 8, 2026 18:49
@RalfJung RalfJung added this pull request to the merge queue Jul 8, 2026
Merged via the queue into rust-lang:master with commit db1e37d Jul 8, 2026
14 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: Waiting for a review to complete label Jul 8, 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.

UnixStream::pair() cannot be read/written

3 participants