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:
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);
- }
- }
- };
- }
- }
- }
-}