import "./core.zc"; import "./vec.zc"; import "./mem.zc"; import "./string.zc"; import "./option.zc"; import "sys/process.zc"; extern struct FILE; struct Output { std_out: String; exit_code: int; } struct Command { program: String; args: Vec; } impl Command { /// Creates a new process builder. fn new(program: char*) -> Command { return Command { program: String::from(program), args: Vec::new() }; } /// Adds a command-line argument. fn arg(self, arg: char*) -> Command* { self.args.push(String::from(arg)); return &self; } fn _build_cmd(self) -> String { let cmd_str = self.program.substring(0, self.program.length()); for arg in &self.args { let space = String::from(" "); cmd_str.append(&space); space.free(); cmd_str.append(arg); } return cmd_str; } /// Returns the captured stdout. fn output(self) -> Output { let cmd_str = self._build_cmd(); let cmd_c = cmd_str.c_str(); let fp = popen(cmd_c, "r"); if (fp == NULL) { cmd_str.free(); return Output { std_out: String::from(""), exit_code: -1 }; } let out = String::from(""); let buf_size: usize = 1024; let buf = alloc_n(buf_size); while (true) { let fgets_res = fgets(buf, (c_int)buf_size, fp); if (fgets_res == NULL) break; let chunk = String::from(buf); out.append(&chunk); chunk.free(); } let code = pclose(fp); dealloc(buf); cmd_str.free(); return Output { std_out: out, exit_code: code }; } fn status(self) -> int { let cmd_str = self._build_cmd(); let code = system(cmd_str.c_str()); cmd_str.free(); return code; } /// Frees the process resources. fn free(self) { self.program.free(); for s in &self.args { s.free(); } self.args.free(); } }