From 92c553382004a29af8fa6f345e2e06bf0191dee7 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 29 Apr 2012 14:37:11 +0200 Subject: [PATCH] Improved the implementation of the exec* functions. --- libmaxsi/include/unistd.h | 13 +++-- libmaxsi/process.cpp | 109 ++++++++++++++++++++++++++++++++++++++ sortix/process.cpp | 8 ++- utils/help.cpp | 2 +- utils/init.cpp | 2 +- utils/ls.cpp | 4 -- utils/mxsh.cpp | 2 +- 7 files changed, 124 insertions(+), 16 deletions(-) diff --git a/libmaxsi/include/unistd.h b/libmaxsi/include/unistd.h index 41362ad4..b879023c 100644 --- a/libmaxsi/include/unistd.h +++ b/libmaxsi/include/unistd.h @@ -31,6 +31,7 @@ #include #if defined(_SORTIX_SOURCE) #include +#include #include #endif #include @@ -93,10 +94,6 @@ char* crypt(const char*, const char*); char* ctermid(char*); int dup2(int, int); void encrypt(char [64], int); -int execl(const char*, const char*, ...); -int execle(const char*, const char*, ...); -int execlp(const char*, const char*, ...); -int execvp(const char*, char* const []); int faccessat(int, const char*, int, int); int fchdir(int); int fchown(int, uid_t, gid_t); @@ -159,8 +156,12 @@ int chdir(const char*); int close(int); int dup(int); void _exit(int); +int execl(const char*, ...); +int execle(const char*, ...); +int execlp(const char*, ...); int execv(const char*, char* const []); int execve(const char*, char* const [], char* const []); +int execvp(const char*, char* const []); pid_t fork(void); int ftruncate(int, off_t); char* getcwd(char*, size_t); @@ -182,6 +183,7 @@ int unlink(const char*); ssize_t write(int, const void*, size_t); #if defined(_SORTIX_SOURCE) +int execvpe(const char*, char* const [], char* const []); size_t getpagesize(void); int memstat(size_t* memused, size_t* memtotal); size_t preadall(int fd, void* buf, size_t count, off_t off); @@ -193,6 +195,9 @@ size_t readleast(int fd, void* buf, size_t least, size_t max); pid_t sfork(int flags); pid_t sforkr(int flags, sforkregs_t* regs); int uptime(uintmax_t* usecssinceboot); +int vexecl(const char*, va_list args); +int vexecle(const char*, va_list args); +int vexeclp(const char*, va_list args); size_t writeall(int fd, const void* buf, size_t count); size_t writeleast(int fd, const void* buf, size_t least, size_t max); #endif diff --git a/libmaxsi/process.cpp b/libmaxsi/process.cpp index 6e8fe123..30cd9a85 100644 --- a/libmaxsi/process.cpp +++ b/libmaxsi/process.cpp @@ -27,8 +27,11 @@ #include #include #include +#include #include #include +#include +#include namespace Maxsi { @@ -65,6 +68,112 @@ namespace Maxsi return execve(pathname, argv, environ); } + // Note that the only PATH variable in Sortix is the one used here. + extern "C" int execvpe(const char* filename, char* const* argv, + char* const* envp) + { + if ( strchr(filename, '/') ) + return execve(filename, argv, envp); + size_t filenamelen = strlen(filename); + const char* PATH = "/bin"; + size_t pathlen = strlen(PATH); + char* pathname = (char*) malloc(filenamelen + 1 + pathlen + 1); + if ( !pathname ) { return -1; } + stpcpy(stpcpy(stpcpy(pathname, PATH), "/"), filename); + int result = execve(pathname, argv, envp); + free(pathname); + return result; + } + + extern "C" int execvp(const char* filename, char* const* argv) + { + return execvpe(filename, argv, environ); + } + + extern "C" int vexecl(const char* pathname, va_list args) + { + va_list iter; + va_copy(iter, args); + size_t numargs = 0; + while ( va_arg(iter, const char*) ) { numargs++; } + va_end(iter); + char** argv = (char**) malloc(sizeof(char*) * (numargs+1)); + if ( !argv ) { return -1; } + for ( size_t i = 0; i <= numargs; i++ ) + { + argv[i] = (char*) va_arg(args, const char*); + } + int result = execv(pathname, argv); + free(argv); + return result; + } + + extern "C" int vexeclp(const char* filename, va_list args) + { + va_list iter; + va_copy(iter, args); + size_t numargs = 0; + while ( va_arg(iter, const char*) ) { numargs++; } + va_end(iter); + char** argv = (char**) malloc(sizeof(char*) * (numargs+1)); + if ( !argv ) { return -1; } + for ( size_t i = 0; i <= numargs; i++ ) + { + argv[i] = (char*) va_arg(args, const char*); + } + int result = execvp(filename, argv); + free(argv); + return result; + } + + extern "C" int vexecle(const char* pathname, va_list args) + { + va_list iter; + va_copy(iter, args); + size_t numargs = 0; + while ( va_arg(iter, const char*) ) { numargs++; } + va_end(iter); + numargs--; // envp + char** argv = (char**) malloc(sizeof(char*) * (numargs+1)); + if ( !argv ) { return -1; } + for ( size_t i = 0; i < numargs; i++ ) + { + argv[i] = (char*) va_arg(args, const char*); + } + argv[numargs] = NULL; + char* const* envp = va_arg(args, char* const*); + int result = execve(pathname, argv, envp); + free(argv); + return result; + } + + extern "C" int execl(const char* pathname, ...) + { + va_list args; + va_start(args, pathname); + int result = vexecl(pathname, args); + va_end(args); + return result; + } + + extern "C" int execlp(const char* filename, ...) + { + va_list args; + va_start(args, filename); + int result = vexeclp(filename, args); + va_end(args); + return result; + } + + extern "C" int execle(const char* pathname, ...) + { + va_list args; + va_start(args, pathname); + int result = vexecle(pathname, args); + va_end(args); + return result; + } + DUAL_FUNCTION(void, exit, Exit, (int status)) { dcloseall(); diff --git a/sortix/process.cpp b/sortix/process.cpp index ac1d20c0..280ac0dc 100644 --- a/sortix/process.cpp +++ b/sortix/process.cpp @@ -411,11 +411,9 @@ namespace Sortix return 0; } - DevBuffer* OpenProgramImage(const char* progname, const char* wd, const char* path) + DevBuffer* OpenProgramImage(const char* progname) { - // TODO: Use the PATH enviromental variable. - const char* base = ( *progname == '.' ) ? wd : path; - char* abs = Directory::MakeAbsolute(base, progname); + char* abs = Directory::MakeAbsolute("/", progname); if ( !abs ) { Error::Set(ENOMEM); return NULL; } // TODO: Use O_EXEC here! @@ -466,7 +464,7 @@ namespace Sortix } Process* process = CurrentProcess(); - state->dev = OpenProgramImage(state->filename, process->workingdir, "/bin"); + state->dev = OpenProgramImage(state->filename); if ( !state->dev ) { delete state; return -1; } state->dev->Refer(); // TODO: Rules of GC may change soon. diff --git a/utils/help.cpp b/utils/help.cpp index ab14dd1c..529a647f 100644 --- a/utils/help.cpp +++ b/utils/help.cpp @@ -31,7 +31,7 @@ int main(int argc, char* argv[]) const char* programname = "ls"; const char* newargv[] = { programname, "/bin", NULL }; - execv(programname, (char* const*) newargv); + execvp(programname, (char* const*) newargv); error(1, errno, "%s", programname); return 1; diff --git a/utils/init.cpp b/utils/init.cpp index 1912dfd8..f317e108 100644 --- a/utils/init.cpp +++ b/utils/init.cpp @@ -33,7 +33,7 @@ int child() const char* programname = "sh"; const char* newargv[] = { programname, NULL }; - execv(programname, (char* const*) newargv); + execvp(programname, (char* const*) newargv); error(0, errno, "%s", programname); return 2; diff --git a/utils/ls.cpp b/utils/ls.cpp index 3d9bccdb..b8bcc959 100644 --- a/utils/ls.cpp +++ b/utils/ls.cpp @@ -34,10 +34,6 @@ #include #include -#if defined(sortix) -#define execvp execv -#endif - bool longformat = false; bool showdotdot = false; bool showdotfiles = false; diff --git a/utils/mxsh.cpp b/utils/mxsh.cpp index 97ae6322..dfddb946 100644 --- a/utils/mxsh.cpp +++ b/utils/mxsh.cpp @@ -214,7 +214,7 @@ readcmd: exit(0); } - execv(argv[0], argv); + execvp(argv[0], argv); error(127, errno, "%s", argv[0]); return 127;