mirror of
https://github.com/openharmony/third_party_rust_mio.git
synced 2026-07-01 20:53:59 -04:00
Don't leak fds on error in UDS on Unix
We do this by simply creating a fd-managing type, e.g. UnixDatagram, from the fd once it's created. Also first tries to parse the path as that can fail without doing a system call.
This commit is contained in:
@@ -7,12 +7,13 @@ use std::os::unix::net;
|
||||
use std::path::Path;
|
||||
|
||||
pub(crate) fn bind(path: &Path) -> io::Result<net::UnixDatagram> {
|
||||
let fd = new_socket(libc::AF_UNIX, libc::SOCK_DGRAM)?;
|
||||
// Ensure the fd is closed.
|
||||
let socket = unsafe { net::UnixDatagram::from_raw_fd(fd) };
|
||||
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))?;
|
||||
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,19 +7,15 @@ use std::path::Path;
|
||||
use std::{io, mem};
|
||||
|
||||
pub(crate) fn bind(path: &Path) -> io::Result<net::UnixListener> {
|
||||
let socket = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
|
||||
let (sockaddr, socklen) = socket_addr(path)?;
|
||||
let sockaddr = &sockaddr as *const libc::sockaddr_un as *const libc::sockaddr;
|
||||
|
||||
syscall!(bind(socket, sockaddr, socklen))
|
||||
.and_then(|_| syscall!(listen(socket, 1024)))
|
||||
.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::UnixListener::from_raw_fd(socket) })
|
||||
let fd = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
|
||||
let socket = unsafe { net::UnixListener::from_raw_fd(fd) };
|
||||
syscall!(bind(fd, sockaddr, socklen))?;
|
||||
syscall!(listen(fd, 1024))?;
|
||||
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, SocketAddr)> {
|
||||
|
||||
@@ -7,23 +7,18 @@ use std::os::unix::net;
|
||||
use std::path::Path;
|
||||
|
||||
pub(crate) fn connect(path: &Path) -> io::Result<net::UnixStream> {
|
||||
let socket = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
|
||||
let (sockaddr, socklen) = socket_addr(path)?;
|
||||
let sockaddr = &sockaddr as *const libc::sockaddr_un as *const libc::sockaddr;
|
||||
|
||||
match syscall!(connect(socket, sockaddr, socklen)) {
|
||||
let fd = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
|
||||
let socket = unsafe { net::UnixStream::from_raw_fd(fd) };
|
||||
match syscall!(connect(fd, sockaddr, socklen)) {
|
||||
Ok(_) => {}
|
||||
Err(ref err) if err.raw_os_error() == Some(libc::EINPROGRESS) => {}
|
||||
Err(e) => {
|
||||
// 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) };
|
||||
|
||||
return Err(e);
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
|
||||
Ok(unsafe { net::UnixStream::from_raw_fd(socket) })
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
pub(crate) fn pair() -> io::Result<(net::UnixStream, net::UnixStream)> {
|
||||
|
||||
Reference in New Issue
Block a user