From 0236fbc21c7f6bcd0bb262c6d6d0519f86c2e28e Mon Sep 17 00:00:00 2001 From: Volker Wysk Date: Fri, 29 Mar 2019 14:34:27 +1100 Subject: [PATCH] extras/posix: Extend exec module. extras/posix/posix.exec.m: Add execvp, execv, execve predicates. --- extras/posix/posix.exec.m | 93 ++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 11 deletions(-) diff --git a/extras/posix/posix.exec.m b/extras/posix/posix.exec.m index bb336dc00..e94de0625 100644 --- a/extras/posix/posix.exec.m +++ b/extras/posix/posix.exec.m @@ -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. %-----------------------------------------------------------------------------%