Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use nix::{
errno::Errno,
fcntl::{
fcntl,
FcntlArg::{F_GETFL, F_SETFD, F_SETFL},
FdFlag, OFlag,
},
libc::{setsockopt, SOL_SOCKET, SO_NOSIGPIPE},
sys::socket::{socketpair, AddressFamily, SockFlag, SockType},
Result,
};
use std::{
mem::size_of,
os::fd::{AsRawFd, BorrowedFd, OwnedFd},
};
pub type ProcessHandle = ();
pub(crate) fn unix_socketpair() -> Result<(OwnedFd, OwnedFd)> {
socketpair(
AddressFamily::Unix,
SockType::Stream,
None,
SockFlag::empty(),
)
}
pub(crate) fn set_socket_default_flags(socket: BorrowedFd) -> Result<()> {
// All our sockets are in non-blocking mode.
let flags = OFlag::from_bits_retain(fcntl(socket, F_GETFL)?);
fcntl(socket, F_SETFL(flags.union(OFlag::O_NONBLOCK)))?;
// TODO: nix doesn't have a safe wrapper for SO_NOSIGPIPE yet, but we need
// to set this flag because we're using stream sockets unlike Linux, where
// we use sequential packets that don't raise SIGPIPE.
let res = unsafe {
setsockopt(
socket.as_raw_fd(),
SOL_SOCKET,
SO_NOSIGPIPE,
(&1 as *const i32).cast(),
size_of::<i32>() as _,
)
};
if res < 0 {
return Err(Errno::last());
}
Ok(())
}
pub(crate) fn set_socket_cloexec(socket: BorrowedFd) -> Result<()> {
fcntl(socket, F_SETFD(FdFlag::FD_CLOEXEC)).map(|_res| ())
}