use std::os::unix::io::FromRawFd;
const LAUNCHD_SOCKET_NAME: &str = "helper";
unsafe extern "C" {
fn launch_activate_socket(
name: *const libc::c_char,
fds: *mut *mut libc::c_int,
cnt: *mut libc::size_t,
) -> libc::c_int;
}
pub fn listener() -> Option<tokio::net::UnixListener> {
let name = std::ffi::CString::new(LAUNCHD_SOCKET_NAME).ok()?;
let mut fds_ptr: *mut libc::c_int = std::ptr::null_mut();
let mut cnt: libc::size_t = 0;
let ret = unsafe { launch_activate_socket(name.as_ptr(), &raw mut fds_ptr, &raw mut cnt) };
if ret != 0 || cnt == 0 || fds_ptr.is_null() {
return None;
}
let fd = unsafe {
let fds = std::slice::from_raw_parts(fds_ptr, cnt);
let first = fds[0];
for &extra in &fds[1..] {
libc::close(extra);
}
libc::free(fds_ptr.cast::<libc::c_void>());
first
};
let std_listener = unsafe { std::os::unix::net::UnixListener::from_raw_fd(fd) };
std_listener.set_nonblocking(true).ok()?;
tokio::net::UnixListener::from_std(std_listener).ok()
}