From 85122893ff2b8cc50b246f0a7dac8c3937d1eaf6 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Wed, 2 Aug 2006 08:00:30 +0000 Subject: [PATCH] - Added the POSIX exec() family functions, based upon code contributed by Henning Nielsen Lund. Thank you very much! - atoll() no longer sets 'errno' directly but now calls __set_errno() instead. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15116 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 5 +++- library/GNUmakefile.os4 | 5 +++- library/changes | 6 ++++ library/include/dos.h | 30 ++++++++++++++++++- library/stdlib_atoll.c | 4 +-- library/unistd_environ.c | 40 ++++++++++++++++++++++++++ library/unistd_execl.c | 4 +-- library/unistd_execv.c | 4 +-- library/unistd_execve.c | 37 ++++++++++++++++++++---- library/unistd_execve_env_exit.c | 47 ++++++++++++++++++++++++++++++ library/unistd_execve_env_init.c | 49 ++++++++++++++++++++++++++++++++ library/unistd_execvp.c | 6 ++-- 12 files changed, 219 insertions(+), 18 deletions(-) create mode 100644 library/unistd_environ.c create mode 100644 library/unistd_execve_env_exit.c create mode 100644 library/unistd_execve_env_init.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index dd97182..8fd6c90 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.91 2006-08-01 17:01:13 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.92 2006-08-02 08:00:27 obarthel Exp $ # # :ts=8 # @@ -529,11 +529,14 @@ UNIX_LIB = \ unistd_common_pathconf.o \ unistd_def_path.o \ unistd_def_path_delimiter.o \ + unistd_environ.o \ unistd_execl.o \ unistd_execle.o \ unistd_execlp.o \ unistd_execv.o \ unistd_execve.o \ + unistd_execve_env_exit.o \ + unistd_execve_env_init.o \ unistd_execvp.o \ unistd_fpathconf.o \ unistd_getcwd.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index 2efda19..7d4d96a 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.104 2006-08-01 17:01:13 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.105 2006-08-02 08:00:27 obarthel Exp $ # # :ts=8 # @@ -572,11 +572,14 @@ UNIX_LIB = \ unistd_common_pathconf.o \ unistd_def_path.o \ unistd_def_path_delimiter.o \ + unistd_environ.o \ unistd_execl.o \ unistd_execle.o \ unistd_execlp.o \ unistd_execv.o \ unistd_execve.o \ + unistd_execve_env_exit.o \ + unistd_execve_env_init.o \ unistd_execvp.o \ unistd_fpathconf.o \ unistd_getcwd.o \ diff --git a/library/changes b/library/changes index 06eced8..8c8eb72 100644 --- a/library/changes +++ b/library/changes @@ -1,3 +1,9 @@ +- Added the POSIX exec() family functions, based upon code contributed + by Henning Nielsen Lund. Thank you very much! + +- atoll() no longer sets 'errno' directly but now calls __set_errno() + instead. + - Added pathconf(), fpathconf(), sysinfo(), ftime(), ulimit(), getrlimit() and setrlimit() as contributed by Peter Bengtsson. Thank you very much! diff --git a/library/include/dos.h b/library/include/dos.h index 9ff4b29..7ed427e 100644 --- a/library/include/dos.h +++ b/library/include/dos.h @@ -1,5 +1,5 @@ /* - * $Id: dos.h,v 1.22 2006-08-01 19:06:48 obarthel Exp $ + * $Id: dos.h,v 1.23 2006-08-02 08:00:30 obarthel Exp $ * * :ts=4 * @@ -499,6 +499,34 @@ extern char * __default_path; /****************************************************************************/ +/* + * 'environ' is the default environment variable table as used by the execl(), + * execv() and execvp() functions. This needs to be initialized before you + * can use it. The table has the following form: + * + * char ** environ = + * { + * "variable1=value", + * "variable2=value", + * NULL + * }; + * + * Note that if you initialize the 'environ' table you will also have to + * provide for a function which prepares its contents in execve() for use + * by the command to be executed. That function is called + * __execve_environ_init(). Should program execution fail, you need to + * clean up after what __execve_environ_init() set up. To do this, call + * __execve_environ_exit(). There are stubs in clib2 for these functions + * which essentially do nothing at all. You will have to implement these + * yourself if you want to use them. + */ +extern char ** environ; + +extern int __execve_environ_init(char * const envp[]); +extern void __execve_environ_exit(char * const envp[]); + +/****************************************************************************/ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/library/stdlib_atoll.c b/library/stdlib_atoll.c index a78bb33..ca99a33 100644 --- a/library/stdlib_atoll.c +++ b/library/stdlib_atoll.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_atoll.c,v 1.2 2006-01-08 12:04:25 obarthel Exp $ + * $Id: stdlib_atoll.c,v 1.3 2006-08-02 08:00:27 obarthel Exp $ * * :ts=4 * @@ -58,7 +58,7 @@ atoll(const char *str) { if(str == NULL) { - errno = EFAULT; + __set_errno(EFAULT); goto out; } } diff --git a/library/unistd_environ.c b/library/unistd_environ.c new file mode 100644 index 0000000..30afc0f --- /dev/null +++ b/library/unistd_environ.c @@ -0,0 +1,40 @@ +/* + * $Id: unistd_environ.c,v 1.1 2006-08-02 08:00:27 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2006 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _UNISTD_HEADERS_H +#include "unistd_headers.h" +#endif /* _UNISTD_HEADERS_H */ + +/****************************************************************************/ + +char ** environ; diff --git a/library/unistd_execl.c b/library/unistd_execl.c index 2bc5d44..ab82664 100644 --- a/library/unistd_execl.c +++ b/library/unistd_execl.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_execl.c,v 1.2 2006-08-02 06:49:47 obarthel Exp $ + * $Id: unistd_execl.c,v 1.3 2006-08-02 08:00:27 obarthel Exp $ * * :ts=4 * @@ -87,7 +87,7 @@ execl(const char *path, const char *arg0, ...) argv[argc] = NULL; - result = execve(path,(char * const *)argv, NULL /*environ*/ ); + result = execve(path,(char * const *)argv,environ); out: diff --git a/library/unistd_execv.c b/library/unistd_execv.c index 12e608b..62ec3e0 100644 --- a/library/unistd_execv.c +++ b/library/unistd_execv.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_execv.c,v 1.2 2006-08-01 17:01:13 obarthel Exp $ + * $Id: unistd_execv.c,v 1.3 2006-08-02 08:00:27 obarthel Exp $ * * :ts=4 * @@ -46,7 +46,7 @@ execv(const char *path,char * const argv[]) { int result; - result = execve(path,argv,NULL /*environ*/); + result = execve(path,argv,environ); return(result); } diff --git a/library/unistd_execve.c b/library/unistd_execve.c index f3a2efd..fb05777 100644 --- a/library/unistd_execve.c +++ b/library/unistd_execve.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_execve.c,v 1.3 2006-08-02 06:49:47 obarthel Exp $ + * $Id: unistd_execve.c,v 1.4 2006-08-02 08:00:27 obarthel Exp $ * * :ts=4 * @@ -302,7 +302,6 @@ find_command(const char * path,struct program_info ** result_ptr) dvp = GetDeviceProc((STRPTR)path,dvp); if(dvp != NULL) { - SetFileSysTask(dvp->dvp_Port); old_dir = CurrentDir(dvp->dvp_Lock); @@ -593,6 +592,18 @@ build_arg_string(char *const argv[],char * arg_string) /****************************************************************************/ +/* NOTE: This is not an execve() function which works like you might expect it + to do on a Unix-like system. Specifically, the command which will + be executed does not replace the currently running program. That + command will be executed first, and when it has returned the currently + running program will exit. Also, if you need to redirect the standard + input/output/error streams you will have to do this using the + equivalent AmigaDOS functions (Open, SelectInput(), SelectOutput() + and SelectErrorOutput()), restoring these streams before your program + exits. What this execve() function does is very similar to how the + built-in AmigaDOS shell works, but it is much more limited in what + it can do. */ + int execve(const char *path, char *const argv[], char *const envp[]) { @@ -604,6 +615,7 @@ execve(const char *path, char *const argv[], char *const envp[]) size_t arg_string_len = 0; size_t parameter_string_len; BOOL success = FALSE; + BOOL clean_up_env = FALSE; BPTR old_dir; LONG rc; @@ -689,6 +701,16 @@ execve(const char *path, char *const argv[], char *const envp[]) arg_string[arg_string_len++] = '\n'; arg_string[arg_string_len] = '\0'; + /* Almost ready: prepare the environment data so that it can + be used by the command to be executed. */ + if(envp != NULL) + { + if(__execve_environ_init(envp) != 0) + goto out; + + clean_up_env = TRUE; + } + /* Change the shell's program name */ GetProgramName(old_program_name,sizeof(old_program_name)); SetProgramName(pi->program_name); @@ -723,16 +745,19 @@ execve(const char *path, char *const argv[], char *const envp[]) out: /* Clean up... */ + if(clean_up_env) + __execve_environ_exit(envp); + + /* If things went well, we can actually quit now. */ + if(success) + exit(result); + if(pi != NULL) free_program_info(pi); if(arg_string != NULL) free(arg_string); - /* If things went well, we can actually quit now. */ - if(success) - exit(result); - /* This function only returns control to the caller if something went wrong... */ return(-1); diff --git a/library/unistd_execve_env_exit.c b/library/unistd_execve_env_exit.c new file mode 100644 index 0000000..79b46a2 --- /dev/null +++ b/library/unistd_execve_env_exit.c @@ -0,0 +1,47 @@ +/* + * $Id: unistd_execve_env_exit.c,v 1.1 2006-08-02 08:00:27 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2006 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _UNISTD_HEADERS_H +#include "unistd_headers.h" +#endif /* _UNISTD_HEADERS_H */ + +/****************************************************************************/ + +/* This is a stub which you need override with your own implementation. The + Function expects a non-NULL pointer to an environment table and will + do whatever is necessary to clean up after what a previous call to the + __execve_environ_init() function did. */ +void +__execve_environ_exit(char * const envp[]) +{ +} diff --git a/library/unistd_execve_env_init.c b/library/unistd_execve_env_init.c new file mode 100644 index 0000000..6be6885 --- /dev/null +++ b/library/unistd_execve_env_init.c @@ -0,0 +1,49 @@ +/* + * $Id: unistd_execve_env_init.c,v 1.1 2006-08-02 08:00:28 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2006 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _UNISTD_HEADERS_H +#include "unistd_headers.h" +#endif /* _UNISTD_HEADERS_H */ + +/****************************************************************************/ + +/* This is a stub which you need override with your own implementation. The + Function expects a non-NULL pointer to an environment table and will + do whatever is necessary to prepare a subsequent call to RunCommand() + to use the environment data. If your function succeeds, return 0 and + a negative value if it fails. */ +int +__execve_environ_init(char * const envp[]) +{ + return(0); +} diff --git a/library/unistd_execvp.c b/library/unistd_execvp.c index 5cde471..14091ea 100644 --- a/library/unistd_execvp.c +++ b/library/unistd_execvp.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_execvp.c,v 1.3 2006-08-02 06:49:47 obarthel Exp $ + * $Id: unistd_execvp.c,v 1.4 2006-08-02 08:00:29 obarthel Exp $ * * :ts=4 * @@ -109,7 +109,7 @@ execvp(const char *command,char * const argv[]) /* If it's an absolute or relative path name, it's easy. */ if(strchr(command,'/') != NULL || strchr(command,':') != NULL) { - result = execve(command, argv, NULL /*environ*/); + result = execve(command, argv, environ); } else { @@ -177,7 +177,7 @@ execvp(const char *command,char * const argv[]) command_buffer[complete_path_len] = '\0'; /* Now try to run that command. */ - result = execve(command_buffer, argv, NULL /*environ*/); + result = execve(command_buffer, argv, environ); /* Did it work? And if it didn't work, did it fail because the command to be run could not be executed? */