luad

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit e3bf89dcdf6588076e04a66bbb150671c84b0854
parent 7c33ceadf4465652dccd2fdac6753a44957b3d9a
Author: Daniel Barlow <dan@telent.net>
Date:   Sun, 17 May 2026 20:38:04 +0100

delete rust stuff and add a Makefile

Diffstat:
DCargo.lock | 257-------------------------------------------------------------------------------
DCargo.toml | 8--------
AMakefile | 8++++++++
MREADME.md | 11++++-------
Mdefault.nix | 14++++----------
Rsrc/luad.c -> luad.c | 0
Drust-toolchain.toml | 2--
Drustup.nix | 46----------------------------------------------
Dsrc/bin/luac.rs | 43-------------------------------------------
Dsrc/main.rs | 235-------------------------------------------------------------------------------
10 files changed, 16 insertions(+), 608 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -1,257 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "bitflags" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" - -[[package]] -name = "bstr" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "cc" -version = "1.2.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "luad" -version = "0.1.0" -dependencies = [ - "libc", - "mlua", -] - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "mlua" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd36acfa49ce6ee56d1307a061dd302c564eee757e6e4cd67eb4f7204846fab" -dependencies = [ - "bstr", - "either", - "libc", - "mlua-sys", - "num-traits", - "parking_lot", - "rustc-hash", - "rustversion", -] - -[[package]] -name = "mlua-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1c3a7fc7580227ece249fd90aa2fa3b39eb2b49d3aec5e103b3e85f2c3dfc8" -dependencies = [ - "cc", - "cfg-if", - "libc", - "pkg-config", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "pkg-config" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "rustc-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" diff --git a/Cargo.toml b/Cargo.toml @@ -1,8 +0,0 @@ -[package] -name = "luad" -version = "0.1.0" -edition = "2024" - -[dependencies] -libc = "0.2.186" -mlua = { version = "0.11.6", features = ["lua53"] } diff --git a/Makefile b/Makefile @@ -0,0 +1,8 @@ +default: luad + +LOADLIBES=-llua +luad: luad.c + +install: + mkdir -p $(TARGET)/bin/ + cp luad $(TARGET)/bin/ diff --git a/README.md b/README.md @@ -22,14 +22,11 @@ Liminix, but it may be useful elsewhere too. * WIP. Not finished. Use at own risk, etc -* it only works on Linux (or if there are other OSes with SCM_RIGHTS -to send unix file descriptors across processes, then maybe it works -on them as well) +* tested only on Linux. Needs SCM_RIGHTS to send unix file descriptors + across processes, which seems to be have [implementation quirks on + different unix flavours](https://gist.github.com/kentonv/bc7592af98c68ba2738f4436920868dc) ## TO DO -[.] run a script in the Lua vm before forking (e.g. to preload -libraries that you want available in every process) - -[.] packaging +[.] implement luac diff --git a/default.nix b/default.nix @@ -3,20 +3,14 @@ lib, lua, pkg-config, - rustPlatform, + stdenv }: -rustPlatform.buildRustPackage (finalAttrs: { +stdenv.mkDerivation { pname = "luad"; version = "0.1.0"; - # this enables rust nightly, required for socket scm_rights interface - env.RUSTC_BOOTSTRAP = 1; src = ./.; - nativeBuildInputs = [ pkg-config ]; buildInputs = [ lua ]; + makeFlags = [ "TARGET=${placeholder "out"}" ]; - cargoLock = { - lockFile = ./Cargo.lock; - }; - -}) +} diff --git a/src/luad.c b/luad.c diff --git a/rust-toolchain.toml b/rust-toolchain.toml @@ -1,2 +0,0 @@ -[toolchain] -channel = "nightly" diff --git a/rustup.nix b/rustup.nix @@ -1,46 +0,0 @@ -{ pkgs ? import <nixpkgs> {} }: - let - overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml)); - libPath = with pkgs; lib.makeLibraryPath [ - # load external libraries that you need in your rust project here - ]; - in - pkgs.mkShell rec { - nativeBuildInputs= with pkgs; [ - openssl - rustup - lua5_3 - pkg-config - ]; - buildInputs = with pkgs; [ - clang - # Replace llvmPackages with llvmPackages_X, where X is the latest LLVM version (at the time of writing, 16) - llvmPackages.bintools - rustup - ]; - RUSTC_VERSION = overrides.toolchain.channel; - # https://github.com/rust-lang/rust-bindgen#environment-variables - LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ]; - shellHook = '' - export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin - export PATH=$PATH:''${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-x86_64-unknown-linux-gnu/bin/ - ''; - # Add precompiled library to rustc search path - RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [ - # add libraries here (e.g. pkgs.libvmi) - ]); - LD_LIBRARY_PATH = libPath; - # Add glibc, clang, glib, and other headers to bindgen search path - BINDGEN_EXTRA_CLANG_ARGS = - # Includes normal include path - (builtins.map (a: ''-I"${a}/include"'') [ - # add dev libraries here (e.g. pkgs.libvmi.dev) - pkgs.glibc.dev - ]) - # Includes with special directory paths - ++ [ - ''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"'' - ''-I"${pkgs.glib.dev}/include/glib-2.0"'' - ''-I${pkgs.glib.out}/lib/glib-2.0/include/'' - ]; - } diff --git a/src/bin/luac.rs b/src/bin/luac.rs @@ -1,43 +0,0 @@ -#![feature(unix_socket_ancillary_data)] - -use std::{ - os::unix::net::{ - UnixDatagram, - SocketAncillary, - SocketAddr - }, - env, - io::IoSlice, - process::exit -}; -use std::os::linux::net::SocketAddrExt; - -fn main() { - let mut payload = "".to_string(); - let mut argv = env::args(); - let _ = argv.next(); - for a in argv { - payload.push_str(&a); - payload.push_str("\0"); - } - let payload = payload.into_bytes(); - let Ok(sock_path) = env::var("LUAD_SOCKET_PATH") else { - panic!("need to set LUAD_SOCKET_PATH env var"); - }; - let pid = std::process::id(); - - let addr = SocketAddr::from_abstract_name(pid.to_le_bytes()).expect("addr"); - let sock = UnixDatagram::bind_addr(&addr).expect("bind"); - - sock.connect(sock_path).expect("connect"); - let fds = [0, 1, 2]; - let mut ancillary_buffer = [0; 128]; - let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); - ancillary.add_fds(&fds[..]); - let buf = IoSlice::new(&payload); - sock.send_vectored_with_ancillary(&[buf], &mut ancillary).expect("send failed"); - - let mut buf : [u8; 4] = [0,0,0,0]; - let _ = sock.recv(&mut buf).unwrap(); - exit(i32::from_be_bytes(buf)); -} diff --git a/src/main.rs b/src/main.rs @@ -1,235 +0,0 @@ -#![feature(unix_socket_ancillary_data)] - -use mlua::Lua; -use std::{ - env, - io::IoSliceMut, - io::Read, - path::Path, - process::exit, - collections::HashMap, - os::fd::AsRawFd -}; - -use std::os::unix::net::{ - UnixDatagram, - SocketAncillary, - AncillaryData, - SocketAddr - -}; - -use libc::{ - pollfd, - poll, - POLLIN, - c_void, - - // fork, - pid_t, - - // wait, - c_int, - - WIFEXITED, - WIFSIGNALED, - WEXITSTATUS, - WTERMSIG -}; - - -enum WaitStatus { - Exited(pid_t, c_int), - Signaled(pid_t, c_int), -} -use crate::WaitStatus::*; - -enum Forked { - Parent(pid_t), - Child, - Err(std::io::Error) -} - -fn fork() -> Forked { - let child_pid = unsafe { libc::fork() }; - if child_pid > 0 { - Forked::Parent(child_pid) - } else if child_pid == 0 { - Forked::Child - } else { - Forked::Err(std::io::Error::last_os_error()) - } -} - -fn wait() -> Result<WaitStatus, std::io::Error> { - let mut wstatus : c_int = 0; - let pid = unsafe { libc::wait(&mut wstatus) }; - if pid >= 0 { - if WIFEXITED(wstatus) { - return Ok(WaitStatus::Exited(pid, WEXITSTATUS(wstatus))) - } else if WIFSIGNALED(wstatus) { - return Ok(WaitStatus::Signaled(pid, WTERMSIG(wstatus))) - } - } - Err(std::io::Error::last_os_error()) -} - -static mut sigchild_fd : i32 = -1; - -extern "C" fn handle_sigchld(_: libc::c_int) { - unsafe { - if sigchild_fd >= 0 { - let _ = libc::write( - sigchild_fd, - "\n".as_ptr() as * const c_void, - 1); - } - } -} - -fn fork_lua(lua : &Lua, args: Vec<String>, fds: Vec<i32>) -> Option<i32> { - let pathname = &args[0]; - let path = Path::new(pathname); - - match fork() { - Forked::Parent(pid) => Some(pid), - Forked::Child => { - for (i, fd) in fds.iter().enumerate() { - unsafe { libc::dup2(*fd, i.try_into().unwrap()); } - }; - let globals = lua.globals(); - if let Ok(arg_table) = lua.create_table() { - for (i, arg) in args.iter().enumerate() { - arg_table.set(i, arg.clone()).expect("arg set failed"); - } - globals.set("arg".to_string(), arg_table).expect("arg set failed"); - } - - let chunk = lua.load(path); - match chunk.exec() { - Ok(()) => { exit(0); }, - Err(e) => { - println!("lua error {:?}", e); - exit(1); - }, - }; - }, - Forked::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); - } - } - } - 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"); - }; - - let Ok((mut sigchild_reader, sigchild_writer)) = std::io::pipe() else { - panic!("failed to open pipe for sigchild") - }; - - unsafe { - sigchild_fd = sigchild_writer.as_raw_fd(); - libc::signal(libc::SIGCHLD, handle_sigchld as *const () as libc::sighandler_t); - }; - let lua = unsafe { Lua::unsafe_new() }; - - let mut argv = env::args(); - argv.next(); - - if let Some(prelude) = argv.next() { - let path = Path::new(&prelude); - println!("preloading {:?}", path); - lua.load(path).exec().expect("load prelude failed"); - } else { - println!("no preload"); - } - - - let sock = UnixDatagram::bind(sock_path)?; - - let mut peers : HashMap<i32, SocketAddr> = HashMap::new(); - - loop { - let mut buf = [0u8; 1024]; - let mut bufs = [ - IoSliceMut::new(&mut buf), - ]; - let mut ancillary_buffer = [0; 128]; - let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); - - let mut pollfds = [ - pollfd { - fd: sock.as_raw_fd(), - events: POLLIN, - revents: 0, - }, - pollfd { - fd: sigchild_reader.as_raw_fd(), - events: POLLIN, - revents: 0, - } - ]; - let n_ready = unsafe { poll(pollfds.as_mut_ptr(), 2, 10000) }; - if n_ready > 0 { - if pollfds[0].revents > 0 { - 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); - } - - }, - Err(e) => { - println!("error reading: {:?}", e); - } - } - }; - if pollfds[1].revents > 0 { - let mut buf = [0u8;1]; - let _ = sigchild_reader.read(&mut buf); - if let Ok(wstatus) = wait() { - if let Some((pid, ret)) = - match wstatus { - Exited(pid, code) => Some((pid, code as u32)), - Signaled(pid, sig) => Some((pid, (sig as u32) + 128)) - } { - if let Some(addr) = peers.get(&pid) { - let _ = sock.send_to_addr(&ret.to_be_bytes(), addr); - } - } - }; - } - } - } -}