That simplifies things a bit.
This code should work:
use std::fs::File;
use std::io;
use std::io::stdin;
use std::os::fd::{AsFd, AsRawFd};
use std::os::linux::net::SocketAddrExt;
use std::os::unix::net::{SocketAddr, UnixListener};
use nix;
use nix::sys::socket::getpeername;
use nix::unistd::dup2_stdin;
pub fn init_fcgi() -> io::Result<UnixListener> {
if getpeername::<()>(stdin().as_raw_fd()) != Err(nix::Error::ENOTCONN) {
return Err(io::Error::other(
"Not a FastCGI application (FD-0 is not a listener socket)",
));
}
let file = File::open("/dev/null")?;
let socket_fd = stdin().as_fd().try_clone_to_owned()?;
dup2_stdin(file)?; // atomically replace stdin
Ok(UnixListener::from(socket_fd))
}
fn main() {
// create dummy listener to test without FastCGI
dup2_stdin(
UnixListener::bind_addr(&SocketAddr::from_abstract_name("fcgi-test").unwrap()).unwrap(),
)
.unwrap();
let socket = init_fcgi().unwrap();
dbg!(socket);
}
Thanks to the nix crate it even avoids unsafe.