use crate::ported::zsh_h::{OPT_ISSET, OPT_ARG, FDT_UNUSED, FDT_EXTERNAL};
pub fn bin_zsocket(nam: &str, args: &[String], ops: &crate::ported::zsh_h::options, _func: i32) -> i32 {
let mut soun: libc::sockaddr_un = unsafe { std::mem::zeroed() };
let mut sfd: i32;
let mut err: i32 = 1; let mut verbose = 0i32;
let mut test = 0i32;
let mut targetfd: i32 = 0;
let mut soun: libc::sockaddr_un = unsafe { std::mem::zeroed() };
let mut sfd: i32;
if OPT_ISSET(ops, b'v') { verbose = 1; } if OPT_ISSET(ops, b't') { test = 1; }
if OPT_ISSET(ops, b'd') { let darg = OPT_ARG(ops, b'd').unwrap_or("");
targetfd = darg.parse::<i32>().unwrap_or(0); if targetfd == 0 { crate::ported::utils::zwarnnam(nam,
&format!("{} is an invalid argument to -d", darg)); return 1; }
if crate::ported::utils::fdtable_get(targetfd) != FDT_UNUSED { crate::ported::utils::zwarnnam(nam, &format!("file descriptor {} is in use by the shell", targetfd));
return 1; }
}
if OPT_ISSET(ops, b'l') { if args.is_empty() { crate::ported::utils::zwarnnam(nam, "-l requires an argument");
return 1; }
let localfn = args[0].as_str(); sfd = unsafe { libc::socket(libc::PF_UNIX, libc::SOCK_STREAM, 0) }; if sfd == -1 { crate::ported::utils::zwarnnam(nam,
&format!("socket error: {} ", std::io::Error::last_os_error())); return 1; }
soun.sun_family = libc::AF_UNIX as _; let path_bytes = localfn.as_bytes();
let max_len = soun.sun_path.len() - 1;
let copy_len = path_bytes.len().min(max_len);
for (k, &b) in path_bytes[..copy_len].iter().enumerate() { soun.sun_path[k] = b as libc::c_char;
}
let r = unsafe { libc::bind(sfd, &soun as *const _ as *const libc::sockaddr,
std::mem::size_of::<libc::sockaddr_un>() as libc::socklen_t)
};
if r != 0 { crate::ported::utils::zwarnnam(nam,
&format!("could not bind to {}: {}", localfn,
std::io::Error::last_os_error())); unsafe { libc::close(sfd); } return 1; }
if unsafe { libc::listen(sfd, 1) } != 0 { crate::ported::utils::zwarnnam(nam,
&format!("could not listen on socket: {}",
std::io::Error::last_os_error())); unsafe { libc::close(sfd); } return 1; }
crate::ported::utils::addmodulefd(sfd); if targetfd != 0 { sfd = crate::ported::utils::redup(sfd, targetfd); } else {
sfd = crate::ported::utils::movefd(sfd); }
if sfd == -1 { crate::ported::utils::zerrnam(nam,
&format!("cannot duplicate fd {}: {}", sfd,
std::io::Error::last_os_error())); return 1; }
crate::ported::utils::fdtable_set(sfd, FDT_EXTERNAL); crate::ported::params::setiparam("REPLY", sfd as i64); if verbose != 0 { println!("{} listener is on fd {}", localfn, sfd); }
return 0; } else if OPT_ISSET(ops, b'a') { if args.is_empty() { crate::ported::utils::zwarnnam(nam, "-a requires an argument");
return 1; }
let lfd = args[0].parse::<i32>().unwrap_or(0); if lfd == 0 { crate::ported::utils::zwarnnam(nam, "invalid numerical argument");
return 1; }
if test != 0 { let mut pfd = libc::pollfd { fd: lfd, events: libc::POLLIN, revents: 0 };
let r = unsafe { libc::poll(&mut pfd, 1, 0) }; if r == 0 { return 1; } else if r == -1 { crate::ported::utils::zwarnnam(nam,
&format!("poll error: {}",
std::io::Error::last_os_error())); return 1; }
}
let mut len: libc::socklen_t =
std::mem::size_of::<libc::sockaddr_un>() as libc::socklen_t; let rfd: i32;
loop { let r = unsafe { libc::accept(lfd, &mut soun as *mut _ as *mut libc::sockaddr, &mut len) };
if r >= 0 { rfd = r; break; }
let osek = std::io::Error::last_os_error().raw_os_error();
if osek != Some(libc::EINTR)
|| crate::ported::utils::errflag
.load(std::sync::atomic::Ordering::Relaxed) != 0 { rfd = r; break; }
}
if rfd == -1 { crate::ported::utils::zwarnnam(nam,
&format!("could not accept connection: {}",
std::io::Error::last_os_error())); return 1; }
crate::ported::utils::addmodulefd(rfd); if targetfd != 0 { sfd = crate::ported::utils::redup(rfd, targetfd); if sfd < 0 { crate::ported::utils::zerrnam(nam,
&format!("could not duplicate socket fd to {}: {}",
targetfd, std::io::Error::last_os_error())); unsafe { libc::close(rfd); } return 1; }
crate::ported::utils::fdtable_set(sfd, FDT_EXTERNAL); } else {
sfd = rfd; }
crate::ported::params::setiparam("REPLY", sfd as i64); if verbose != 0 { let path = soun.sun_path.iter()
.take_while(|&&c| c != 0)
.map(|&c| c as u8 as char).collect::<String>();
println!("new connection from {} is on fd {}", path, sfd); }
} else { if args.is_empty() { crate::ported::utils::zwarnnam(nam, "zsocket requires an argument");
return 1; }
sfd = unsafe { libc::socket(libc::PF_UNIX, libc::SOCK_STREAM, 0) }; if sfd == -1 { crate::ported::utils::zwarnnam(nam,
&format!("socket creation failed: {}",
std::io::Error::last_os_error())); return 1; }
soun.sun_family = libc::AF_UNIX as _; let path_bytes = args[0].as_bytes();
let max_len = soun.sun_path.len() - 1;
let copy_len = path_bytes.len().min(max_len);
for (k, &b) in path_bytes[..copy_len].iter().enumerate() { soun.sun_path[k] = b as libc::c_char;
}
err = unsafe { libc::connect(sfd,
&soun as *const _ as *const libc::sockaddr,
std::mem::size_of::<libc::sockaddr_un>() as libc::socklen_t)
};
if err != 0 { crate::ported::utils::zwarnnam(nam,
&format!("connection failed: {}",
std::io::Error::last_os_error())); unsafe { libc::close(sfd); } return 1; }
crate::ported::utils::addmodulefd(sfd); if targetfd != 0 { if crate::ported::utils::redup(sfd, targetfd) < 0 { crate::ported::utils::zerrnam(nam,
&format!("could not duplicate socket fd to {}: {}",
targetfd, std::io::Error::last_os_error())); unsafe { libc::close(sfd); } return 1; }
sfd = targetfd; crate::ported::utils::fdtable_set(sfd, FDT_EXTERNAL); }
crate::ported::params::setiparam("REPLY", sfd as i64); if verbose != 0 { let path = &args[0];
println!("{} is now on fd {}", path, sfd); }
}
let _ = (err, verbose, test, targetfd); 0 }
use crate::ported::zsh_h::module;
#[allow(unused_variables)]
pub fn setup_(m: *const module) -> i32 { 0 }
pub fn features_(m: *const module, features: &mut Vec<String>) -> i32 { *features = featuresarray(m, module_features());
0 }
pub fn enables_(m: *const module, enables: &mut Option<Vec<i32>>) -> i32 { handlefeatures(m, module_features(), enables) }
#[allow(unused_variables)]
pub fn boot_(m: *const module) -> i32 { 0 }
pub fn cleanup_(m: *const module) -> i32 { setfeatureenables(m, module_features(), None) }
#[allow(unused_variables)]
pub fn finish_(m: *const module) -> i32 { 0 }
use crate::ported::zsh_h::features as features_t;
use std::sync::{Mutex, OnceLock};
static MODULE_FEATURES: OnceLock<Mutex<features_t>> = OnceLock::new();
fn module_features() -> &'static Mutex<features_t> {
MODULE_FEATURES.get_or_init(|| Mutex::new(features_t {
bn_list: None,
bn_size: 1,
cd_list: None,
cd_size: 0,
mf_list: None,
mf_size: 0,
pd_list: None,
pd_size: 0,
n_abstract: 0,
}))
}
fn featuresarray(_m: *const module, _f: &Mutex<features_t>) -> Vec<String> {
vec!["b:zsocket".to_string()]
}
fn handlefeatures(
_m: *const module,
_f: &Mutex<features_t>,
enables: &mut Option<Vec<i32>>,
) -> i32 {
if enables.is_none() {
*enables = Some(vec![1; 1]);
}
0
}
fn setfeatureenables(
_m: *const module,
_f: &Mutex<features_t>,
_e: Option<&[i32]>,
) -> i32 {
0
}