Skip to content

Instantly share code, notes, and snippets.

@talex5
Last active July 12, 2016 01:45
Show Gist options
  • Save talex5/5656435 to your computer and use it in GitHub Desktop.
Save talex5/5656435 to your computer and use it in GitHub Desktop.
My attempt at a Rust replacement for 0install's _runenv.py
/* Rust version of this Python code:
import os, sys, json
envname = os.path.basename(sys.argv[0])
args = json.loads(os.environ["0install-runenv-" + envname])
os.execv(args[0], args + sys.argv[1:])
*/
extern mod std;
use std::json;
use std::json::{List, String};
use core::libc::funcs::posix88::unistd;
macro_rules! expect(
($e:expr, $v:ident, $err:expr) => (
match $e {
$v(ref x) => x,
_ => fail!($err)
}
);
)
fn json_list_to_str_vector(jp: &json::Json) -> ~[~str] {
let jl = expect!(*jp, List, ~"Not a JSON list");
let mut results = ~[];
for vec::each(*jl) |x: &json::Json| {
let s: ~str = copy *expect!(*x, String, ~"Not a JSON string");
results.push(s);
}
results
}
// This should really be in the standard library
fn execv(argv: &mut [~str]) -> ! {
let mut argv_raw: ~[*i8] = ~[];
for vec::each_mut(argv) |x: &mut ~str| {
let l = x.len();
unsafe {
str::raw::set_len(x, l); // Ensure null-terminated
do str::as_c_str(*x) |x: *i8| {
argv_raw.push(x);
}
}
}
argv_raw.push(ptr::null());
do vec::as_imm_buf(argv_raw) |buf, _len| {
unsafe { unistd::execv(*buf, cast::transmute(buf)) };
};
fail!(fmt!("execv failed: %?", argv));
}
// argv[0] is the name of the symlink used to invoke us (e.g. "make"). We look for a corresponding
// environment variable to tell us how to invoke make. This variable is a list of arguments for execv.
fn main() {
let our_args = os::args();
let prog :path::PosixPath = path::Path(our_args[0]);
let basename :&str = prog.filename().expect(fmt!("Not a file '%?'", prog));
let var :~str = ~"0install-runenv-" + basename;
let json_str = os::getenv(var).expect(fmt!("Environment varibale '%s' not set", var));
let j: json::Json = json::from_str(json_str).unwrap();
let mut prog_args: ~[~str] = json_list_to_str_vector(&j);
prog_args += our_args.tail();
execv(prog_args);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment