forked from facebook/flow
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript_utils.ml
More file actions
87 lines (80 loc) · 2.51 KB
/
script_utils.ml
File metadata and controls
87 lines (80 loc) · 2.51 KB
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
(*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
let with_pipe f =
let (fd_r, fd_w) = Unix.pipe () in
try
let res = f (fd_r, fd_w) in
Unix.close fd_r;
Unix.close fd_w;
res
with
| exn ->
Unix.close fd_r;
Unix.close fd_w;
raise exn
let with_in_channel filename f =
let ic = open_in_bin filename in
try
let res = f ic in
close_in ic;
res
with
| exn ->
close_in ic;
raise exn
let with_out_channel filename f =
let oc = open_out_bin filename in
try
let res = f oc in
close_out oc;
res
with
| exn ->
close_out oc;
raise exn
let read_process name args (in_r, _in_w) (out_r, out_w) (err_r, err_w) =
let pid =
try Unix.create_process name args in_r out_w err_w with
| Unix.Unix_error (Unix.ENOENT, _, _) ->
(* On Windows, this is what happens if you call create_process
* non_existent_thing *)
raise (Failure (name ^ ": command not found"))
in
match Unix.waitpid [] pid with
| (_, Unix.WEXITED 0) -> input_line (Unix.in_channel_of_descr out_r)
| (_, Unix.WEXITED 127) ->
(* On Linux & OSX, this is what happens if you call create_process
* non_existent_thing *)
raise (Failure (name ^ ": command not found"))
| (_, Unix.WEXITED 128) -> raise (Failure (input_line (Unix.in_channel_of_descr err_r)))
| (_, Unix.WEXITED code) -> raise (Failure (name ^ ": exited code " ^ string_of_int code))
| (_, Unix.WSIGNALED signal) ->
raise (Failure (name ^ ": killed by signal " ^ string_of_int signal))
| (_, Unix.WSTOPPED signal) ->
raise (Failure (name ^ ": stopped by signal " ^ string_of_int signal))
(* Read the first line in stdout or stderr of an external command. *)
let read_process_output name args =
with_pipe @@ fun in_pipe ->
with_pipe @@ fun out_pipe -> read_process name args in_pipe out_pipe out_pipe
(* Read the first line in stdout of an external command. *)
let read_process_stdout name args =
with_pipe @@ fun in_pipe ->
with_pipe @@ fun out_pipe ->
with_pipe @@ fun err_pipe -> read_process name args in_pipe out_pipe err_pipe
let string_of_file filename =
with_in_channel filename @@ fun ic ->
let s = Bytes.create 32759 in
let b = Buffer.create 1000 in
let rec iter ic b s =
let nread = input ic s 0 32759 in
if nread > 0 then (
Buffer.add_subbytes b s 0 nread;
iter ic b s
)
in
iter ic b s;
Buffer.contents b