Improved the implementation of the exec* functions.

This commit is contained in:
Jonas 'Sortie' Termansen 2012-04-29 14:37:11 +02:00
parent 93abeda32e
commit 92c5533820
7 changed files with 124 additions and 16 deletions

View File

@ -31,6 +31,7 @@
#include <features.h>
#if defined(_SORTIX_SOURCE)
#include <stdint.h>
#include <stdarg.h>
#include <sortix/fork.h>
#endif
#include <sortix/seek.h>
@ -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

View File

@ -27,8 +27,11 @@
#include <libmaxsi/syscall.h>
#include <libmaxsi/process.h>
#include <stdio.h>
#include <stdarg.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
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();

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -34,10 +34,6 @@
#include <error.h>
#include <fcntl.h>
#if defined(sortix)
#define execvp execv
#endif
bool longformat = false;
bool showdotdot = false;
bool showdotfiles = false;

View File

@ -214,7 +214,7 @@ readcmd:
exit(0);
}
execv(argv[0], argv);
execvp(argv[0], argv);
error(127, errno, "%s", argv[0]);
return 127;