Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unix.open_process_args_*: look up program in PATH #10084

Merged
merged 9 commits into from
Dec 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ Working version

### Other libraries:

* #10084: Unix.open_process_args* functions now look up the program in the PATH.
This was already the case under Windows, but this is now also done under
Unix. Note that previously the program was interpreted relative to the current
directory.
(Nicolás Ojeda Bär, review by Gabriel Scherer and Xavier Leroy)

### Tools:

### Manual and documentation:
Expand Down
10 changes: 5 additions & 5 deletions otherlibs/unix/unix.ml
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ let system cmd =
let pid = spawn shell [| shell; "-c"; cmd |] None false [| 0; 1; 2 |] in
snd(waitpid_non_intr pid)

let create_process_gen usepath cmd args optenv
let create_process_gen cmd args optenv
new_stdin new_stdout new_stderr =
let toclose = ref [] in
let close_after () =
Expand All @@ -917,13 +917,13 @@ let create_process_gen usepath cmd args optenv
(if new_stderr = 2 then 2 else file_descr_not_standard new_stderr)
|] in
Fun.protect ~finally:close_after
(fun () -> spawn cmd args optenv usepath redirections)
(fun () -> spawn cmd args optenv true (* usepath *) redirections)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if spawn is not exported, we should make usepath a labelled argument instead of using comments to alleviate the problems of non-labelled boolean arguments.

(Looking at the code, I see that spawn is an external. Can external have labels too?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Externals can have labeled and even optional arguments. There are examples elsewhere in this unix.ml file.

This said, spawn is not exported, and is called only twice in unix.ml, so it doesn't need to have a bulletproof interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'm not adding a label as it seems a bit overkill in this case...


let create_process cmd args new_stdin new_stdout new_stderr =
create_process_gen true cmd args None new_stdin new_stdout new_stderr
create_process_gen cmd args None new_stdin new_stdout new_stderr

let create_process_env cmd args env new_stdin new_stdout new_stderr =
create_process_gen true cmd args (Some env) new_stdin new_stdout new_stderr
create_process_gen cmd args (Some env) new_stdin new_stdout new_stderr

type popen_process =
Process of in_channel * out_channel
Expand All @@ -935,7 +935,7 @@ let popen_processes = (Hashtbl.create 7 : (popen_process, int) Hashtbl.t)

let open_proc prog args envopt proc input output error =
let pid =
create_process_gen false prog args envopt input output error in
create_process_gen prog args envopt input output error in
Hashtbl.add popen_processes proc pid

let open_process_args_in prog args =
Expand Down
38 changes: 21 additions & 17 deletions otherlibs/unix/unix.mli
Original file line number Diff line number Diff line change
Expand Up @@ -875,38 +875,42 @@ val open_process_full :
{!open_process_full}. *)

val open_process_args_in : string -> string array -> in_channel
(** High-level pipe and process management. The first argument specifies the
command to run, and the second argument specifies the argument array passed
to the command. This function runs the command in parallel with the program.
The standard output of the command is redirected to a pipe, which can be read
via the returned input channel.
(** [open_process_args_in prog args] runs the program [prog] with arguments
[args]. The new process executes concurrently with the current process.
The standard output of the new process is redirected to a pipe, which can be
read via the returned input channel.

The executable file [prog] is searched in the path. This behaviour changed
in 4.12; previously [prog] was looked up only in the current directory.

The new process has the same environment as the current process.

@since 4.08.0 *)

val open_process_args_out : string -> string array -> out_channel
(** Same as {!open_process_args_in}, but redirect the standard input of the
command to a pipe. Data written to the returned output channel is sent to
the standard input of the command. Warning: writes on output channels are
buffered, hence be careful to call {!Stdlib.flush} at the right times to
ensure correct synchronization.
(** Same as {!open_process_args_in}, but redirect the standard input of the new
process to a pipe. Data written to the returned output channel is sent to
the standard input of the program. Warning: writes on output channels are
buffered, hence be careful to call {!Stdlib.flush} at the right times to
ensure correct synchronization.

@since 4.08.0 *)

val open_process_args : string -> string array -> in_channel * out_channel
(** Same as {!open_process_args_out}, but redirects both the standard input
and standard output of the command to pipes connected to the two returned
channels. The input channel is connected to the output of the command, and
the output channel to the input of the command.
(** Same as {!open_process_args_out}, but redirects both the standard input and
standard output of the new process to pipes connected to the two returned
channels. The input channel is connected to the output of the program, and
the output channel to the input of the program.

@since 4.08.0 *)

val open_process_args_full :
string -> string array -> string array ->
in_channel * out_channel * in_channel
(** Similar to {!open_process_args}, but the third argument specifies the
environment passed to the command. The result is a triple of channels
connected respectively to the standard output, standard input, and standard
error of the command.
environment passed to the new process. The result is a triple of channels
connected respectively to the standard output, standard input, and standard
error of the program.

@since 4.08.0 *)

Expand Down
38 changes: 21 additions & 17 deletions otherlibs/unix/unixLabels.mli
Original file line number Diff line number Diff line change
Expand Up @@ -875,38 +875,42 @@ val open_process_full :
{!open_process_full}. *)

val open_process_args_in : string -> string array -> in_channel
(** High-level pipe and process management. The first argument specifies the
command to run, and the second argument specifies the argument array passed
to the command. This function runs the command in parallel with the program.
The standard output of the command is redirected to a pipe, which can be read
via the returned input channel.
(** [open_process_args_in prog args] runs the program [prog] with arguments
[args]. The new process executes concurrently with the current process.
The standard output of the new process is redirected to a pipe, which can be
read via the returned input channel.

The executable file [prog] is searched in the path. This behaviour changed
in 4.12; previously [prog] was looked up only in the current directory.

The new process has the same environment as the current process.

@since 4.08.0 *)

val open_process_args_out : string -> string array -> out_channel
(** Same as {!open_process_args_in}, but redirect the standard input of the
command to a pipe. Data written to the returned output channel is sent to
the standard input of the command. Warning: writes on output channels are
buffered, hence be careful to call {!Stdlib.flush} at the right times to
ensure correct synchronization.
(** Same as {!open_process_args_in}, but redirect the standard input of the new
process to a pipe. Data written to the returned output channel is sent to
the standard input of the program. Warning: writes on output channels are
buffered, hence be careful to call {!Stdlib.flush} at the right times to
ensure correct synchronization.

@since 4.08.0 *)

val open_process_args : string -> string array -> in_channel * out_channel
(** Same as {!open_process_args_out}, but redirects both the standard input
and standard output of the command to pipes connected to the two returned
channels. The input channel is connected to the output of the command, and
the output channel to the input of the command.
(** Same as {!open_process_args_out}, but redirects both the standard input and
standard output of the new process to pipes connected to the two returned
channels. The input channel is connected to the output of the program, and
the output channel to the input of the program.

@since 4.08.0 *)

val open_process_args_full :
string -> string array -> string array ->
in_channel * out_channel * in_channel
(** Similar to {!open_process_args}, but the third argument specifies the
environment passed to the command. The result is a triple of channels
connected respectively to the standard output, standard input, and standard
error of the command.
environment passed to the new process. The result is a triple of channels
connected respectively to the standard output, standard input, and standard
error of the program.

@since 4.08.0 *)

Expand Down