1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | module OUnix = Unix open Core.Std open Async.Std type pid = int type t = { pid : pid ; stdin : Writer.t ; stdout : Reader.t ; stderr : Reader.t } type cmd_exit = [ `Exited of int | `Signal of int | `Unknown ] let read_all r = let b = Buffer.create 1024 in let rec read_all' () = let str = String.create 4096 in Reader.read r str >>= function | `Ok n -> begin Buffer.add_substring b str 0 n; read_all' () end | `Eof -> begin let _ = Reader.close r in Deferred.return (Buffer.contents b) end in read_all' () let wait pi = In_thread.run (fun () -> match OUnix.waitpid [] pi.pid with | (_, OUnix.WEXITED exit_code) -> `Exited exit_code | (_, OUnix.WSIGNALED signal) -> `Signal signal | _ -> `Unknown) let run ~prog ~args = let (c_stdin, m_stdin) = OUnix.pipe () and (m_stdout, c_stdout) = OUnix.pipe () and (m_stderr, c_stderr) = OUnix.pipe () in let pid = OUnix.create_process prog (Array.of_list (prog::args)) c_stdin c_stdout c_stderr in OUnix.close c_stdin; OUnix.close c_stdout; OUnix.close c_stderr; let module K = Async.Std.Fd.Kind in Deferred.return { pid = pid ; stdin = Writer.create (Fd.create K.File m_stdin ~name:"stdin") ; stdout = Reader.create (Fd.create K.File m_stdout ~name:"stdout") ; stderr = Reader.create (Fd.create K.File m_stderr ~name:"stderr") } let background d = let ret = Ivar.create () in whenever (d >>| fun r -> Ivar.fill ret r); ret let get_output ~text ~prog ~args = run ~prog:prog ~args:args >>= fun pi -> Writer.write pi.stdin text; Writer.close pi.stdin >>= fun () -> let stdout = background (read_all pi.stdout) in let stderr = background (read_all pi.stderr) in wait pi >>= function | `Exited 0 -> Deferred.both (Ivar.read stdout) (Ivar.read stderr) >>= fun (stdout, stderr) -> Deferred.return (Result.Ok (stdout, stderr)) | err -> Deferred.both (Ivar.read stdout) (Ivar.read stderr) >>= fun (stdout, stderr) -> Deferred.return (Result.Error (err, (stdout, stderr))) let async_cmd_get_output_test () = get_output ~text:"testing" ~prog:"cat" ~args:[] >>= fun _ -> Printf.printf "DONE!\n"; Deferred.return 0 let test () = upon (async_cmd_get_output_test ()) (fun ret -> never_returns (Shutdown.shutdown_and_raise ret)) let () = test (); never_returns (Scheduler.go ()) |
bW9kdWxlIE9Vbml4ID0gVW5peApvcGVuIENvcmUuU3RkCm9wZW4gQXN5bmMuU3RkCgp0eXBlIHBpZCA9IGludAoKdHlwZSB0ID0geyBwaWQgICAgOiBwaWQKCSA7IHN0ZGluICA6IFdyaXRlci50CgkgOyBzdGRvdXQgOiBSZWFkZXIudAoJIDsgc3RkZXJyIDogUmVhZGVyLnQKCSB9Cgp0eXBlIGNtZF9leGl0ID0gWyBgRXhpdGVkIG9mIGludCB8IGBTaWduYWwgb2YgaW50IHwgYFVua25vd24gXQoKbGV0IHJlYWRfYWxsIHIgPQogIGxldCBiID0gQnVmZmVyLmNyZWF0ZSAxMDI0CiAgaW4KICBsZXQgcmVjIHJlYWRfYWxsJyAoKSA9CiAgICBsZXQgc3RyID0gU3RyaW5nLmNyZWF0ZSA0MDk2CiAgICBpbgogICAgUmVhZGVyLnJlYWQgciBzdHIgPj49IGZ1bmN0aW9uCiAgICAgIHwgYE9rIG4gLT4gYmVnaW4KCUJ1ZmZlci5hZGRfc3Vic3RyaW5nIGIgc3RyIDAgbjsKCXJlYWRfYWxsJyAoKQogICAgICBlbmQKICAgICAgfCBgRW9mICAtPiBiZWdpbgoJbGV0IF8gPSBSZWFkZXIuY2xvc2UgciBpbgoJRGVmZXJyZWQucmV0dXJuIChCdWZmZXIuY29udGVudHMgYikKICAgICAgZW5kCiAgaW4KICByZWFkX2FsbCcgKCkKCmxldCB3YWl0IHBpID0KICBJbl90aHJlYWQucnVuCiAgICAoZnVuICgpIC0+CiAgICAgIG1hdGNoIE9Vbml4LndhaXRwaWQgW10gcGkucGlkIHdpdGgKCXwgKF8sIE9Vbml4LldFWElURUQgZXhpdF9jb2RlKSAtPgoJICBgRXhpdGVkIGV4aXRfY29kZQoJfCAoXywgT1VuaXguV1NJR05BTEVEIHNpZ25hbCkgLT4KCSAgYFNpZ25hbCBzaWduYWwKCXwgXyAtPgoJICBgVW5rbm93bikKCmxldCBydW4gfnByb2cgfmFyZ3MgPQogIGxldCAoY19zdGRpbiwgbV9zdGRpbikgICA9IE9Vbml4LnBpcGUgKCkKICBhbmQgKG1fc3Rkb3V0LCBjX3N0ZG91dCkgPSBPVW5peC5waXBlICgpCiAgYW5kIChtX3N0ZGVyciwgY19zdGRlcnIpID0gT1VuaXgucGlwZSAoKQogIGluCiAgbGV0IHBpZCA9CiAgICBPVW5peC5jcmVhdGVfcHJvY2VzcwogICAgICBwcm9nCiAgICAgIChBcnJheS5vZl9saXN0IChwcm9nOjphcmdzKSkKICAgICAgY19zdGRpbgogICAgICBjX3N0ZG91dAogICAgICBjX3N0ZGVycgogIGluCiAgT1VuaXguY2xvc2UgY19zdGRpbjsKICBPVW5peC5jbG9zZSBjX3N0ZG91dDsKICBPVW5peC5jbG9zZSBjX3N0ZGVycjsKICBsZXQgbW9kdWxlIEsgPSBBc3luYy5TdGQuRmQuS2luZAogIGluCiAgRGVmZXJyZWQucmV0dXJuCiAgICB7IHBpZCA9IHBpZAogICAgOyBzdGRpbiAgPSBXcml0ZXIuY3JlYXRlIChGZC5jcmVhdGUgSy5GaWxlIG1fc3RkaW4gfm5hbWU6InN0ZGluIikKICAgIDsgc3Rkb3V0ID0gUmVhZGVyLmNyZWF0ZSAoRmQuY3JlYXRlIEsuRmlsZSBtX3N0ZG91dCB+bmFtZToic3Rkb3V0IikKICAgIDsgc3RkZXJyID0gUmVhZGVyLmNyZWF0ZSAoRmQuY3JlYXRlIEsuRmlsZSBtX3N0ZGVyciB+bmFtZToic3RkZXJyIikKICAgIH0KCmxldCBiYWNrZ3JvdW5kIGQgPQogIGxldCByZXQgPSBJdmFyLmNyZWF0ZSAoKSBpbgogIHdoZW5ldmVyIChkID4+fCBmdW4gciAtPiBJdmFyLmZpbGwgcmV0IHIpOwogIHJldAoKbGV0IGdldF9vdXRwdXQgfnRleHQgfnByb2cgfmFyZ3MgPQogIHJ1biB+cHJvZzpwcm9nIH5hcmdzOmFyZ3MgPj49IGZ1biBwaSAtPgogIFdyaXRlci53cml0ZSBwaS5zdGRpbiB0ZXh0OwogIFdyaXRlci5jbG9zZSBwaS5zdGRpbiA+Pj0gZnVuICgpIC0+CiAgbGV0IHN0ZG91dCA9IGJhY2tncm91bmQgKHJlYWRfYWxsIHBpLnN0ZG91dCkgaW4KICBsZXQgc3RkZXJyID0gYmFja2dyb3VuZCAocmVhZF9hbGwgcGkuc3RkZXJyKSBpbgogIHdhaXQgcGkgPj49IGZ1bmN0aW9uCiAgICB8IGBFeGl0ZWQgMCAtPgogICAgICBEZWZlcnJlZC5ib3RoIChJdmFyLnJlYWQgc3Rkb3V0KSAoSXZhci5yZWFkIHN0ZGVycikgPj49IGZ1biAoc3Rkb3V0LCBzdGRlcnIpIC0+CiAgICAgIERlZmVycmVkLnJldHVybiAoUmVzdWx0Lk9rIChzdGRvdXQsIHN0ZGVycikpCiAgICB8IGVyciAtPgogICAgICBEZWZlcnJlZC5ib3RoIChJdmFyLnJlYWQgc3Rkb3V0KSAoSXZhci5yZWFkIHN0ZGVycikgPj49IGZ1biAoc3Rkb3V0LCBzdGRlcnIpIC0+CiAgICAgIERlZmVycmVkLnJldHVybiAoUmVzdWx0LkVycm9yIChlcnIsIChzdGRvdXQsIHN0ZGVycikpKQoKCmxldCBhc3luY19jbWRfZ2V0X291dHB1dF90ZXN0ICgpID0KICBnZXRfb3V0cHV0IH50ZXh0OiJ0ZXN0aW5nIiB+cHJvZzoiY2F0IiB+YXJnczpbXSA+Pj0gZnVuIF8gLT4KICBQcmludGYucHJpbnRmICJET05FIVxuIjsKICBEZWZlcnJlZC5yZXR1cm4gMAoKbGV0IHRlc3QgKCkgPQogIHVwb24KICAgIChhc3luY19jbWRfZ2V0X291dHB1dF90ZXN0ICgpKQogICAgKGZ1biByZXQgLT4gbmV2ZXJfcmV0dXJucyAoU2h1dGRvd24uc2h1dGRvd25fYW5kX3JhaXNlIHJldCkpCgoKbGV0ICgpID0KICB0ZXN0ICgpOwogIG5ldmVyX3JldHVybnMgKFNjaGVkdWxlci5nbyAoKSkK
File "prog.ml", line 2, characters 0-13: Unbound module Core.Std
-
result: Compilation error (maybe you wish to see an example for Ocaml)


