diary @ telent

It's ironic - Rust in Liminix#

Sat May 16 19:40:05 2026

Topics: liminix rust

tl;dr I thought there was was going to be some Rust in Liminix, but it turns out there isn't. I'm not opposed to adding it, but the application I thought I had for it turns out to be better done in C

I'd better eludicate. I decided, way back in whenever-it-was, that Fennel would be the go-to "scripting" language for anything in Liminix too complicated to want to write it in ash-compatible sh - and as my criterion for "too complicated" is more than about ten lines long, that's quite a lot of Fennel. The Fennel is translated to Lua at build time and interpreted by the lua command at runtime. So we start many Lua VMs and in most of them we load anoia.lua and lualinux.so which together provide functionality that pretty much every such script requires.

I thought it would be a useful optimisation to have a server that spawns prewarmed Lua VMs on demand. I should say upfront that this is premature optimisation in its purest form as I haven't even measured how long these things take to load.

So what it does is start a lua interpreter and listen on a socket. On each incoming conection it reads the name of a lua script and accepts file descriptors for stdin/stdout/stderr as ancillary data. It forks, and run the script in the child so its state does not change the state of the parent. I'm pretty sure I've seen this pattern a bunch of times (something KDE did back in the day, Ruby snailgun gem) but I can't now find a good reference describing it or naming it, so if you haven't seen it before maybe I dreamt it. It's not "preforking" because there's no pool of children - they're forked on connect.

And the reason I wrote it without first finding out of it'd be useful is it seemed like an excuse to try using Rust again.

What I found:

The surprisingly simple bit was incorporating it into Liminix. I added my package to overlay.nix and ran nix-build and voila, a MIPS binary. I was expecting to have to swear a bit more than that.

However, I'm not going to do it, because the binary is huge. After stripping it, replacing the fork and nix crate dependencies with direct libc calls, and then following this handy guide to reducing binary size I've got it from somewhere north of 800k to around 415k, but that's still a significant chunk of a 16MB flash filesystem. When I wrote the equivalent program in C for comparison it's about 20k. Yes, both are linked dynamically against libc and liblua.

So, the outcome of the experiment is I have no current plans to add Rust to Liminix. But if it ever turns out that we do need to, at least we know it's possible.

Maybe I should try Zig.