extras/posix: Extend exec module.

extras/posix/posix.exec.m:
    Add execvp, execv, execve predicates.
This commit is contained in:
Volker Wysk
2019-03-29 14:34:27 +11:00
committed by Peter Wang
parent c544da19f3
commit 0236fbc21c

View File

@@ -24,9 +24,22 @@
:- type env == map(string, string).
:- pred execvp(string::in, argv::in, posix.result::out,
io::di, io::uo) is det.
:- pred execv(string::in, argv::in, posix.result::out,
io::di, io::uo) is det.
:- pred execve(string::in, argv::in, env::in, posix.result::out,
io::di, io::uo) is det.
:- pred exec(string::in, argv::in, env::in, posix.result::out,
io::di, io::uo) is det.
% This is a GNU extension, and not included:
% :- pred execvpe(string::in, argv::in, env::in, posix.result::out,
% io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -72,23 +85,26 @@
Array[i] = NULL;
").
%-----------------------------------------------------------------------------%
exec(Command, Args, Env, Result, !IO) :-
make_string_array(Args, ArgsArray),
make_string_array(map(variable, map.to_assoc_list(Env)), EnvArray),
exec0(Command, ArgsArray, EnvArray, !IO),
errno(Err, !IO),
Result = error(Err).
:- func variable(pair(string)) = string.
variable(Name - Value) = Name ++ "=" ++ Value.
:- pred exec0(string::in, string_array::in, string_array::in, io::di, io::uo)
%-----------------------------------------------------------------------------%
%
% int execve(const char *filename, char *const argv[], char *const envp[]);
%
execve(Command, Args, Env, Result, !IO) :-
make_string_array(Args, ArgsArray),
make_string_array(map(variable, map.to_assoc_list(Env)), EnvArray),
execve0(Command, ArgsArray, EnvArray, !IO),
errno(Err, !IO),
Result = error(Err).
:- pred execve0(string::in, string_array::in, string_array::in, io::di, io::uo)
is det.
:- pragma foreign_proc("C",
exec0(Command::in, ArgsArray::in, EnvArray::in, _IO0::di, _IO::uo),
execve0(Command::in, ArgsArray::in, EnvArray::in, _IO0::di, _IO::uo),
[promise_pure, will_not_call_mercury, tabled_for_io],
"
int ret;
@@ -98,6 +114,61 @@ variable(Name - Value) = Name ++ "=" ++ Value.
} while (ret == -1 && MR_is_eintr(errno));
").
%-----------------------------------------------------------------------------%
%
% int execvp(const char *file, char *const argv[]);
%
execvp(Command, Args, Result, !IO) :-
make_string_array(Args, ArgsArray),
execvp0(Command, ArgsArray, !IO),
errno(Err, !IO),
Result = error(Err).
:- pred execvp0(string::in, string_array::in, io::di, io::uo)
is det.
:- pragma foreign_proc("C",
execvp0(Command::in, ArgsArray::in, _IO0::di, _IO::uo),
[promise_pure, will_not_call_mercury, tabled_for_io],
"
int ret;
do {
ret = execvp(Command, ArgsArray);
} while (ret == -1 && MR_is_eintr(errno));
").
%-----------------------------------------------------------------------------%
%
% int execv(const char *path, char *const argv[]);
%
execv(Command, Args, Result, !IO) :-
make_string_array(Args, ArgsArray),
execv0(Command, ArgsArray, !IO),
errno(Err, !IO),
Result = error(Err).
:- pred execv0(string::in, string_array::in, io::di, io::uo)
is det.
:- pragma foreign_proc("C",
execv0(Command::in, ArgsArray::in, _IO0::di, _IO::uo),
[promise_pure, will_not_call_mercury, tabled_for_io],
"
int ret;
do {
ret = execv(Command, ArgsArray);
} while (ret == -1 && MR_is_eintr(errno));
").
%-----------------------------------------------------------------------------%
%
% Synonym for execve, for backwards compatibility
exec(Command, Args, Env, Result, !IO) :-
execve(Command, Args, Env, Result, !IO).
%-----------------------------------------------------------------------------%
:- end_module posix.exec.
%-----------------------------------------------------------------------------%