parse the datagram payload and fork lua on the file
This commit is contained in:
+74
-49
@@ -13,27 +13,66 @@ use std::{
|
||||
use std::os::unix::net::{
|
||||
UnixDatagram,
|
||||
SocketAncillary,
|
||||
AncillaryData
|
||||
AncillaryData,
|
||||
SocketAddr
|
||||
|
||||
};
|
||||
|
||||
use libc::WEXITSTATUS;
|
||||
use fork::{Fork, fork, waitpid};
|
||||
|
||||
// if we use SCM_RIGHTS to pass fds from client, we also need to
|
||||
// write the client as we can't do that with socat
|
||||
fn fork_lua(lua : &Lua, args: Vec<String>, fds: Vec<i32>) -> Option<i32> {
|
||||
let pathname = &args[0];
|
||||
|
||||
fn run_lua(lua : &Lua, path : &Path) {
|
||||
let chunk = lua.load(path);
|
||||
match chunk.exec() {
|
||||
Ok(()) => { println!("lua returned ok"); },
|
||||
Err(e) => {
|
||||
println!("lua error {:?}", e);
|
||||
exit(1);
|
||||
let path = Path::new(pathname);
|
||||
match fork() {
|
||||
Ok(Fork::Parent(pid)) => Some(pid),
|
||||
Ok(Fork::Child) => {
|
||||
for (i, fd) in fds.iter().enumerate() {
|
||||
unsafe { libc::dup2(*fd, i.try_into().unwrap()); }
|
||||
};
|
||||
let chunk = lua.load(path);
|
||||
match chunk.exec() {
|
||||
Ok(()) => { println!("lua returned ok"); },
|
||||
Err(e) => {
|
||||
println!("lua error {:?}", e);
|
||||
exit(1);
|
||||
},
|
||||
};
|
||||
exit(0);
|
||||
},
|
||||
};
|
||||
exit(0);
|
||||
Err(e) => {
|
||||
println!("fork error {:?}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_ancillary_data(ancillary : SocketAncillary<'_>) -> Vec<i32> {
|
||||
let mut fds : Vec<i32> = Vec::new();
|
||||
for ancillary_result in ancillary.messages() {
|
||||
if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
|
||||
for fd in scm_rights {
|
||||
println!("receive file descriptor: {fd}");
|
||||
fds.push(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("fds {:?}", fds);
|
||||
fds
|
||||
}
|
||||
|
||||
fn split_command(buf : &[u8]) -> Vec<String> {
|
||||
let mut words : Vec<String> = Vec::new();
|
||||
for w in buf.split(|e| *e == 0) {
|
||||
if let Ok(s) = str::from_utf8(w) {
|
||||
words.push(s.to_string());
|
||||
}
|
||||
}
|
||||
words
|
||||
}
|
||||
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let Ok(sock_path) = env::var("LUAD_SOCKET_PATH") else {
|
||||
panic!("need to set LUAD_SOCKET_PATH env var");
|
||||
@@ -43,6 +82,7 @@ fn main() -> std::io::Result<()> {
|
||||
|
||||
let sock = UnixDatagram::bind(sock_path)?;
|
||||
|
||||
let mut peers : HashMap<i32, SocketAddr> = HashMap::new();
|
||||
// listen for datagrams. each time we get one, fork a child
|
||||
// to run lua script with the datagram payload and its stdio
|
||||
// connected to the passed fds. when the lua subprocess exits,
|
||||
@@ -56,50 +96,35 @@ fn main() -> std::io::Result<()> {
|
||||
];
|
||||
let mut ancillary_buffer = [0; 128];
|
||||
let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
|
||||
match sock.recv_vectored_with_ancillary(&mut bufs, &mut ancillary) {
|
||||
Ok((size, truncated)) => {
|
||||
let mut fds : Vec<i32> = Vec::new();
|
||||
for ancillary_result in ancillary.messages() {
|
||||
if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
|
||||
for fd in scm_rights {
|
||||
println!("receive file descriptor: {fd}");
|
||||
fds.push(fd);
|
||||
}
|
||||
}
|
||||
match sock.recv_vectored_with_ancillary_from(&mut bufs, &mut ancillary) {
|
||||
Ok((size, truncated, peer)) => {
|
||||
let fds = read_ancillary_data(ancillary);
|
||||
let args = split_command(&buf[..size-1]);
|
||||
println!("args {:?} from {:?}", args, peer);
|
||||
if let Some(child) = fork_lua(&lua, args, fds) {
|
||||
println!("forked {child}");
|
||||
peers.insert(child, peer);
|
||||
}
|
||||
println!("data {:?}, len {:?}", buf, size);
|
||||
println!("fds {:?}", fds);
|
||||
|
||||
},
|
||||
Err(e) => {
|
||||
println!("error reading: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// // println!("parent {:?} {:?}", pid, result);
|
||||
// match waitpid(pid) {
|
||||
// Ok(status) => {
|
||||
// println!("exited {:?}", WEXITSTATUS(status));
|
||||
// },
|
||||
// Err(e) => {
|
||||
// println!("waitpid failed {:?}", e);
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
|
||||
|
||||
}
|
||||
|
||||
// for pathname in io::stdin().lines() {
|
||||
// let pathname = pathname.unwrap();
|
||||
// let path = Path::new(&pathname);
|
||||
// match fork() {
|
||||
// Ok(Fork::Parent(pid)) => {
|
||||
// // println!("parent {:?} {:?}", pid, result);
|
||||
// match waitpid(pid) {
|
||||
// Ok(status) => {
|
||||
// println!("exited {:?}", WEXITSTATUS(status));
|
||||
// },
|
||||
// Err(e) => {
|
||||
// println!("waitpid failed {:?}", e);
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// Ok(Fork::Child) => {
|
||||
// run_lua(&lua, &path);
|
||||
// }
|
||||
// Err(e) => {
|
||||
// println!("fork error {:?}", e);
|
||||
// exit(1);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user