miri
miri copied to clipboard
Complete socketpair support
We pretend to implement socketpair
, but that's a complete lie. Completing this however doesn't need any involvement with the rest of the epoll plans. We "just" need to allocate somewhere two buffers for the data to be sent between these two endpoints, and then wire up the read/write of the two sockets with the right buffers. This can be tested by directly using socketpair
/read
/write
.
There's also https://github.com/rust-lang/miri/issues/3231.
We can provide more detailed mentoring instructions if needed.
I think this should follow the proposed "project" process: https://github.com/rust-lang/miri/issues/3443.
I wonder if there are libc compliance test suites that are licensed well enough for us to extract tests from
Hi, I am planning to work on this first since it is related to #3448. I will send the link to the proposal here once I finished localtime_r
.
@rustbot claim
Error: The feature assign
is not enabled in this repository.
To enable it add its section in the triagebot.toml
in the root of the repository.
Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.
I wonder if there are libc compliance test suites that are licensed well enough for us to extract tests from
Hmm I couldn't find any test for libc for now, if anyone knows where can I find one please let me know, thanks. Currently I imagine minimally the test should look like this (Note: they wrapped libc around their API, so it looks slightly different)
#[test]
pub fn test_socketpair() {
use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType};
use nix::unistd::{read, write};
let (fd1, fd2) = socketpair(
AddressFamily::Unix,
SockType::Stream,
None,
SockFlag::empty(),
)
.unwrap();
write(&fd1, b"hello").unwrap();
let mut buf = [0; 5];
read(fd2.as_raw_fd(), &mut buf).unwrap();
assert_eq!(&buf[..], b"hello");
}
//source: https://github.com/nix-rust/nix/blob/590ab4d5d0b6228f0529b036e4f8a42265ba6d31/test/sys/test_socket.rs#L311.
I might add similar test in the proposal that I am going to send soon.
This is the proposal for socketpair
shim: https://hackmd.io/@tiif/Skhc1t0-C. It is still under development, more attention is needed for the problems below:
- Should we block
write
when the buffer is full? - How can miri differentiate
read
andwrite
ofsocketpair
file descriptors and other kind of file descriptors?
Feel free to provide any ideas or suggestion especially for the buffer mechanism part.
2. How can miri differentiate
read
andwrite
ofsocketpair
file descriptors and other kind of file descriptors?
Why does it need to? Shouldn't the abstraction provided by the FileDescriptor
trait hide all thatvand only the socket pair type implementing that trait would care?
Left some comments,on the doc
Should we block write when the buffer is full?
Yes, we should.
How can miri differentiate read and write of socketpair file descriptors and other kind of file descriptors?
As Oli said: you "just" have to implement the read
and write
functions of the SocketPair type; the general file descriptor machinery will make sure to dispatch to that when read
/write
is called on an FD that is (part of) a socketpair.
This is the proposal for socketpair shim: https://hackmd.io/@tiif/Skhc1t0-C. It is still under development, more attention is needed for the problems below:
Thanks! The API description is very helpful. I have left some comments.
What is missing for me is a plan for how the Miri state looks like. In particular, the proposal should say what the fields of struct SocketPair
will be. I currently think it will likely be something like
struct SocketPair {
write_buf: Rc<SocketBuf>,
read_buf: Rc<SocketBuf>,
}
but that then raises the question of what the fields of SocketBuf
are. :) Maybe data: VecDeque<u8>
as you sketched out is sufficient.
FWIW, once this is done it should be fairly easy to also support pipe
/pipe2
. Those are basically just one-directional sockets, for our purposes.