Last active
July 12, 2016 01:45
-
-
Save talex5/5656435 to your computer and use it in GitHub Desktop.
My attempt at a Rust replacement for 0install's _runenv.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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