-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathCCUnix.mli
185 lines (149 loc) · 5.65 KB
/
CCUnix.mli
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
(* This file is free software, part of containers. See file "license" for more details. *)
(** {1 High-level Functions on top of Unix}
Some useful functions built on top of Unix.
{b status: unstable}
@since 0.10 *)
type 'a or_error = ('a, string) Result.result
type 'a gen = unit -> 'a option
(** {2 Calling Commands} *)
val escape_str : string -> string
(** Escape a string so it can be a shell argument. *)
(*$T
escape_str "foo" = "foo"
escape_str "foo bar" = "'foo bar'"
escape_str "fo'o b'ar" = "'fo'\\''o b'\\''ar'"
*)
type call_result =
< stdout:string;
stderr:string;
status:Unix.process_status;
errcode:int; (** Extracted from status *)
>
val call_full :
?bufsize:int ->
?stdin:[`Gen of string gen | `Str of string] ->
?env:string array ->
('a, Buffer.t, unit, call_result) format4 ->
'a
(** [call_full cmd] wraps the result of [Unix.open_process_full cmd] into an
object. It reads the full stdout and stderr of the subprocess before
returning.
@param stdin if provided, the generator or string is consumed and fed to
the subprocess input channel, which is then closed.
@param bufsize buffer size used to read stdout and stderr
@param env environment to run the command in
*)
(*$T
call_full ~stdin:(`Str "abc") "cat" |> stdout = "abc"
call_full "echo %s" (escape_str "a'b'c") |> stdout = "a'b'c\n"
call_full "echo %s" "a'b'c" |> stdout = "abc\n"
*)
val call :
?bufsize:int ->
?stdin:[`Gen of string gen | `Str of string] ->
?env:string array ->
('a, Buffer.t, unit, string * string * int) format4 ->
'a
(** [call cmd] is similar to [call_full cmd] but returns
a tuple [stdout, stderr, errcode] instead of an object. *)
val call_stdout :
?bufsize:int ->
?stdin:[`Gen of string gen | `Str of string] ->
?env:string array ->
('a, Buffer.t, unit, string) format4 ->
'a
(*$T
call_stdout ~stdin:(`Str "abc") "cat" = "abc"
call_stdout "echo %s" (escape_str "a'b'c") = "a'b'c\n"
call_stdout "echo %s" "a'b'c" = "abc\n"
*)
type line = string
type async_call_result =
< stdout:line gen;
stderr:line gen;
stdin:line -> unit; (* send a line *)
close_in:unit; (* close stdin *)
close_err:unit;
close_out:unit;
close_all:unit; (* close all 3 channels *) (** @since 0.11 *)
wait:Unix.process_status; (* block until the process ends *)
wait_errcode:int; (* block until the process ends, then extract errcode *)
(** @since 0.11 *)
>
(** A subprocess for interactive usage (read/write channels line by line)
@since 0.11 *)
val async_call : ?env:string array ->
('a, Buffer.t, unit, async_call_result) format4 ->
'a
(** Spawns a subprocess, like {!call}, but the subprocess's channels are
line generators and line sinks (for stdin).
if [p] is [async_call "cmd"], then [p#wait] waits for the subprocess
to die. Channels can be closed independently.
@since 0.11 *)
(** {2 Accessors}
@since 0.11 *)
val stdout : < stdout : 'a; .. > -> 'a
val stderr : < stderr : 'a; .. > -> 'a
val status : < status : 'a; .. > -> 'a
val errcode : < errcode : 'a; .. > -> 'a
(** {2 Simple IO} *)
val with_in : ?mode:int -> ?flags:Unix.open_flag list ->
string -> f:(in_channel -> 'a) -> 'a
(** Open an input file with the given optional flag list, calls the function
on the input channel. When the function raises or returns, the
channel is closed.
@param flags opening flags. [Unix.O_RDONLY] is used in any cases
@since 0.16 *)
val with_out : ?mode:int -> ?flags:Unix.open_flag list ->
string -> f:(out_channel -> 'a) -> 'a
(** Same as {!with_in} but for an output channel
@param flags opening flags (default [[Unix.O_CREAT; Unix.O_TRUNC]])
[Unix.O_WRONLY] is used in any cases.
@since 0.16 *)
val with_process_in : string -> f:(in_channel -> 'a) -> 'a
(** Open a subprocess and obtain a handle to its stdout
{[
CCUnix.with_process_in "ls /tmp" ~f:CCIO.read_lines_l;;
]}
@since 0.16 *)
val with_process_out : string -> f:(out_channel -> 'a) -> 'a
(** Open a subprocess and obtain a handle to its stdin
@since 0.16 *)
(** Handle to a subprocess.
@since 0.16 *)
type process_full = <
stdin: out_channel;
stdout: in_channel;
stderr: in_channel;
close: Unix.process_status; (** Will block until the process stops *)
>
val with_process_full : ?env:string array -> string -> f:(process_full -> 'a) -> 'a
(** Open a subprocess and obtain a handle to its channels.
@param env environment to pass to the subprocess.
@since 0.16 *)
val with_connection : Unix.sockaddr -> f:(in_channel -> out_channel -> 'a) -> 'a
(** Wrap {!Unix.open_connection} with a handler
@since 0.16 *)
exception ExitServer
val establish_server : Unix.sockaddr -> f:(in_channel -> out_channel -> _) -> unit
(** Listen on the address and calls the handler in a blocking fashion.
Using {!Thread} is recommended if handlers might take time.
The callback should raise {!ExitServer} to stop the loop.
@since 0.16 *)
val with_file_lock : kind:[`Read|`Write] -> string -> (unit -> 'a) -> 'a
(** [with_file_lock ~kind filename f] puts a lock on the offset 0
of the file named [filename], calls [f] and returns its result after
the file is unlocked. If [f ()] raises an exception the exception is
re-raised after the file is unlocked.
@param kind specifies whether the lock is read-only or read-write.
@since 1.2 *)
(** {2 Infix Functions} *)
module Infix : sig
val (?|) : ('a, Buffer.t, unit, call_result) format4 -> 'a
(** Infix version of {!call}
@since 0.11 *)
val (?|&) : ('a, Buffer.t, unit, async_call_result) format4 -> 'a
(** Infix version of {!async_call}
@since 0.11 *)
end
include module type of Infix