Change:
This bug was found and mitigated by the Wine project here: The types for each setsockopt are documented here: As the Wine commit explains, Windows itself is more liberal in what values of optlen it will accept for boolean arguments, which is why this has not affected Windows proper, but it would still be better to pass the expected type and length, so that the Rust bindings will also work on more strict implementations of winsock, such as Wine's prior to this fix. I confirmed that this is the case using Wine 7.0, which is the current stable branch available from Wine 5.0.3, which is the version that Debian/Ubuntu distribute themselves, is not affected by this problem. I tried this code: I set up a listening peer with , built with , and ran with . I expected to see this happen: all the socket operations succeed, and prints "hello" and exits. Instead, this happened: setnodelay returns an Err: If I run with , which shows the Linux system calls that wine makes on behalf of the program, I can see: I tested this using rust 1.58.1, but I confirmed that the code in question is still doing the same thing on the branch of rust. Here is a commit which should fix the issue: I was able to test it myself and confirmed that the error goes away: That this error isn't formatted correctly is probably another bug, but I haven't looked into it.
Thanks for reporting this! Would you mind creating a pull request with your changes? The rustc dev guide has information on the .
Sure thing:

Discussion:
} pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { <del> net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BYTE) </del> <ins> net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BOOL) </ins> } pub fn nodelay(&self) -> io::Result<bool> { <del> let raw: c::BYTE = net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?; </del> <ins> let raw: c::BOOL = net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?; </ins> Ok(raw != 0) }

// sockaddr and misc bindings //////////////////////////////////////////////////////////////////////////////// <del> pub fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int, payload: T) -> io::Result<()> { </del> <ins> pub fn setsockopt<T>( sock: &Socket, level: c_int, option_name: c_int, option_value: T, ) -> io::Result<()> { </ins> unsafe { <del> let payload = &payload as *const T as *const c_void; cvt(c::setsockopt(sock.as_raw(), opt, val, payload, mem::size_of::<T>() as c::socklen_t))?; </del> <ins> cvt(c::setsockopt( sock.as_raw(), level, option_name, &option_value as *const T as *const _, mem::size_of::<T>() as c::socklen_t, ))?; </ins> Ok(()) } } <del> pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int, val: c_int) -> io::Result<T> { </del> <ins> pub fn getsockopt<T: Copy>(sock: &Socket, level: c_int, option_name: c_int) -> io::Result<T> { </ins> unsafe { <del> let mut slot: T = mem::zeroed(); let mut len = mem::size_of::<T>() as c::socklen_t; cvt(c::getsockopt(sock.as_raw(), opt, val, &mut slot as *mut _ as *mut _, &mut len))?; assert_eq!(len as usize, mem::size_of::<T>()); Ok(slot) </del> <ins> let mut option_value: T = mem::zeroed(); let mut option_len = mem::size_of::<T>() as c::socklen_t; cvt(c::getsockopt( sock.as_raw(), level, option_name, &mut option_value as *mut T as *mut _, &mut option_len, ))?; Ok(option_value) </ins> } }