Make fd handling code consistent for Unix

Now all the fd creating code follows the following pattern.

let raw_fd = create_fd();
let managed_fd = wrap(raw_fd);
// Additional system calls
return managed_fd
This commit is contained in:
Thomas de Zeeuw
2022-11-28 11:22:43 +01:00
parent 7e5c50c283
commit 427ab37712
4 changed files with 24 additions and 39 deletions
+3 -2
View File
@@ -176,7 +176,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> {
|| libc::fcntl(*fd, libc::F_SETFD, libc::FD_CLOEXEC) != 0
{
let err = io::Error::last_os_error();
// Don't leak file descriptors. Can't handle error though.
// Don't leak file descriptors. Can't handle closing error though.
let _ = libc::close(fds[0]);
let _ = libc::close(fds[1]);
return Err(err);
@@ -198,9 +198,10 @@ pub fn new() -> io::Result<(Sender, Receiver)> {
)))]
compile_error!("unsupported target for `mio::unix::pipe`");
// Safety: we just initialised the `fds` above.
// SAFETY: we just initialised the `fds` above.
let r = unsafe { Receiver::from_raw_fd(fds[0]) };
let w = unsafe { Sender::from_raw_fd(fds[1]) };
Ok((w, r))
}
+6 -14
View File
@@ -6,21 +6,13 @@ use std::net::{self, SocketAddr};
use std::os::unix::io::{AsRawFd, FromRawFd};
pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
// Gives a warning for non Apple platforms.
#[allow(clippy::let_and_return)]
let socket = new_ip_socket(addr, libc::SOCK_DGRAM);
let fd = new_ip_socket(addr, libc::SOCK_DGRAM)?;
let socket = unsafe { net::UdpSocket::from_raw_fd(fd) };
socket.and_then(|socket| {
let (raw_addr, raw_addr_length) = socket_addr(&addr);
syscall!(bind(socket, raw_addr.as_ptr(), raw_addr_length))
.map_err(|err| {
// Close the socket if we hit an error, ignoring the error
// from closing since we can't pass back two errors.
let _ = unsafe { libc::close(socket) };
err
})
.map(|_| unsafe { net::UdpSocket::from_raw_fd(socket) })
})
let (raw_addr, raw_addr_length) = socket_addr(&addr);
syscall!(bind(fd, raw_addr.as_ptr(), raw_addr_length))?;
Ok(socket)
}
pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {
+4 -5
View File
@@ -10,16 +10,15 @@ pub(crate) fn bind(path: &Path) -> io::Result<net::UnixDatagram> {
let (sockaddr, socklen) = socket_addr(path)?;
let sockaddr = &sockaddr as *const libc::sockaddr_un as *const _;
let fd = new_socket(libc::AF_UNIX, libc::SOCK_DGRAM)?;
let socket = unsafe { net::UnixDatagram::from_raw_fd(fd) };
syscall!(bind(fd, sockaddr, socklen))?;
let socket = unbound()?;
syscall!(bind(socket.as_raw_fd(), sockaddr, socklen))?;
Ok(socket)
}
pub(crate) fn unbound() -> io::Result<net::UnixDatagram> {
new_socket(libc::AF_UNIX, libc::SOCK_DGRAM)
.map(|socket| unsafe { net::UnixDatagram::from_raw_fd(socket) })
let fd = new_socket(libc::AF_UNIX, libc::SOCK_DGRAM)?;
Ok(unsafe { net::UnixDatagram::from_raw_fd(fd) })
}
pub(crate) fn pair() -> io::Result<(net::UnixDatagram, net::UnixDatagram)> {
+11 -18
View File
@@ -20,14 +20,11 @@ mod eventfd {
impl Waker {
pub fn new(selector: &Selector, token: Token) -> io::Result<Waker> {
syscall!(eventfd(0, libc::EFD_CLOEXEC | libc::EFD_NONBLOCK)).and_then(|fd| {
// Turn the file descriptor into a file first so we're ensured
// it's closed when dropped, e.g. when register below fails.
let file = unsafe { File::from_raw_fd(fd) };
selector
.register(fd, token, Interest::READABLE)
.map(|()| Waker { fd: file })
})
let fd = syscall!(eventfd(0, libc::EFD_CLOEXEC | libc::EFD_NONBLOCK))?;
let file = unsafe { File::from_raw_fd(fd) };
selector.register(fd, token, Interest::READABLE)?;
Ok(Waker { fd: file })
}
pub fn wake(&self) -> io::Result<()> {
@@ -82,11 +79,9 @@ mod kqueue {
impl Waker {
pub fn new(selector: &Selector, token: Token) -> io::Result<Waker> {
selector.try_clone().and_then(|selector| {
selector
.setup_waker(token)
.map(|()| Waker { selector, token })
})
let selector = selector.try_clone()?;
selector.setup_waker(token)?;
Ok(Waker { selector, token })
}
pub fn wake(&self) -> io::Result<()> {
@@ -127,13 +122,11 @@ mod pipe {
pub fn new(selector: &Selector, token: Token) -> io::Result<Waker> {
let mut fds = [-1; 2];
syscall!(pipe2(fds.as_mut_ptr(), libc::O_NONBLOCK | libc::O_CLOEXEC))?;
// Turn the file descriptors into files first so we're ensured
// they're closed when dropped, e.g. when register below fails.
let sender = unsafe { File::from_raw_fd(fds[1]) };
let receiver = unsafe { File::from_raw_fd(fds[0]) };
selector
.register(fds[0], token, Interest::READABLE)
.map(|()| Waker { sender, receiver })
selector.register(fds[0], token, Interest::READABLE)?;
Ok(Waker { sender, receiver })
}
pub fn wake(&self) -> io::Result<()> {