|
| 1 | +import _str.sbuf; |
| 2 | +import _vec.vbuf; |
| 3 | + |
| 4 | +native "rust" mod rustrt { |
| 5 | + fn rust_run_program(vbuf argv, int in_fd, int out_fd, int err_fd) -> int; |
| 6 | +} |
| 7 | + |
| 8 | +fn argvec(str prog, vec[str] args) -> vec[sbuf] { |
| 9 | + auto argptrs = vec(_str.buf(prog)); |
| 10 | + for (str arg in args) { |
| 11 | + argptrs = _vec.push[sbuf](argptrs, _str.buf(arg)); |
| 12 | + } |
| 13 | + argptrs = _vec.push[sbuf](argptrs, 0 as sbuf); |
| 14 | + ret argptrs; |
| 15 | +} |
| 16 | + |
| 17 | +impure fn run_program(str prog, vec[str] args) -> int { |
| 18 | + auto pid = rustrt.rust_run_program(_vec.buf[sbuf](argvec(prog, args)), |
| 19 | + 0, 0, 0); |
| 20 | + ret os.waitpid(pid); |
| 21 | +} |
| 22 | + |
| 23 | +type program = |
| 24 | + state obj { |
| 25 | + fn get_id() -> int; |
| 26 | + fn input() -> io.writer; |
| 27 | + fn output() -> io.reader; |
| 28 | + impure fn close_input(); |
| 29 | + impure fn finish() -> int; |
| 30 | + }; |
| 31 | + |
| 32 | +impure fn start_program(str prog, vec[str] args) -> @program { |
| 33 | + auto pipe_input = os.pipe(); |
| 34 | + auto pipe_output = os.pipe(); |
| 35 | + auto pid = rustrt.rust_run_program |
| 36 | + (_vec.buf[sbuf](argvec(prog, args)), |
| 37 | + pipe_input._0, pipe_output._1, 0); |
| 38 | + if (pid == -1) {fail;} |
| 39 | + os.libc.close(pipe_input._0); |
| 40 | + os.libc.close(pipe_output._1); |
| 41 | + |
| 42 | + state obj new_program(int pid, |
| 43 | + int in_fd, |
| 44 | + os.libc.FILE out_file, |
| 45 | + mutable bool finished) { |
| 46 | + fn get_id() -> int {ret pid;} |
| 47 | + fn input() -> io.writer { |
| 48 | + ret io.new_writer(io.fd_buf_writer(in_fd, false)); |
| 49 | + } |
| 50 | + fn output() -> io.reader { |
| 51 | + ret io.FILE_reader(out_file, false); |
| 52 | + } |
| 53 | + impure fn close_input() { |
| 54 | + os.libc.close(in_fd); |
| 55 | + } |
| 56 | + impure fn finish() -> int { |
| 57 | + if (finished) {ret 0;} |
| 58 | + finished = true; |
| 59 | + os.libc.close(in_fd); |
| 60 | + ret os.waitpid(pid); |
| 61 | + } |
| 62 | + drop { |
| 63 | + if (!finished) { |
| 64 | + os.libc.close(in_fd); |
| 65 | + os.waitpid(pid); |
| 66 | + } |
| 67 | + os.libc.fclose(out_file); |
| 68 | + } |
| 69 | + } |
| 70 | + ret @new_program(pid, pipe_input._1, |
| 71 | + os.fd_FILE(pipe_output._0), |
| 72 | + false); |
| 73 | +} |
| 74 | + |
| 75 | +impure fn program_output(str prog, vec[str] args) |
| 76 | + -> rec(int status, str out) { |
| 77 | + auto pr = start_program(prog, args); |
| 78 | + pr.close_input(); |
| 79 | + auto out = pr.output(); |
| 80 | + auto buf = ""; |
| 81 | + while (!out.eof()) { |
| 82 | + auto bytes = out.read_bytes(4096u); |
| 83 | + buf += _str.unsafe_from_bytes(bytes); |
| 84 | + } |
| 85 | + ret rec(status=pr.finish(), out=buf); |
| 86 | +} |
| 87 | + |
| 88 | + |
| 89 | +// Local Variables: |
| 90 | +// mode: rust |
| 91 | +// fill-column: 78; |
| 92 | +// indent-tabs-mode: nil |
| 93 | +// c-basic-offset: 4 |
| 94 | +// buffer-file-coding-system: utf-8-unix |
| 95 | +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; |
| 96 | +// End: |
0 commit comments