diff options
Diffstat (limited to 'libc/syscall')
-rw-r--r-- | libc/syscall/Makefile | 4 | ||||
-rw-r--r-- | libc/syscall/exec.c (renamed from libc/syscall/execve.c) | 88 | ||||
-rw-r--r-- | libc/syscall/mksys386 | 30 |
3 files changed, 102 insertions, 20 deletions
diff --git a/libc/syscall/Makefile b/libc/syscall/Makefile index 06728da..b487655 100644 --- a/libc/syscall/Makefile +++ b/libc/syscall/Makefile @@ -16,8 +16,8 @@ LSRC0=syslib0.c LOBJ0=__cstartup.o lseek.o getpid.o getppid.o getuid.o geteuid.o getgid.o \ getegid.o dup2.o dup.o getpgrp.o times.o -ESRC=execve.c -E2OBJ=execl.o execv.o execle.o +ESRC=exec.c +E2OBJ=execl.o execv.o execle.o execlp.o execvp.o EOBJ=execve.o $(E2OBJ) DSRC=dirent.c diff --git a/libc/syscall/execve.c b/libc/syscall/exec.c index 33643ca..411b744 100644 --- a/libc/syscall/execve.c +++ b/libc/syscall/exec.c @@ -1,5 +1,6 @@ #include <errno.h> +#include <sys/stat.h> extern char ** environ; @@ -113,9 +114,91 @@ char ** envp; } #endif -#ifdef L_execvve +#ifdef L_execlp int -execvve(fname, interp, argv, envp) +execlp(fname, arg0) +char * fname, *arg0; +{ + return execvp(fname, &arg0); +} +#endif + +#ifdef L_execvp +int +execvp(fname, argv) +char * fname, **argv; +{ + char *pname = fname, *path; + int besterr = ENOENT; + int flen, plen; + char * bp = sbrk(0); + + if( *fname != '/' && (path = getenv("PATH")) != 0 ) + { + flen = strlen(fname)+2; + + for(;path;) + { + if( *path == ':' || *path == '\0' ) + { + tryrun(fname, argv); + if( errno == EACCES ) besterr = EACCES; + if( *path ) path++; else break; + } + else + { + char * p = strchr(path, ':'); + if(p) *p = '\0'; + plen = strlen(path); + pname = sbrk(plen+flen); + + strcpy(pname, path); + strcat(pname, "/"); + strcat(pname, fname); + + tryrun(pname, argv); + if( errno == EACCES ) besterr = EACCES; + + brk(pname); + pname = fname; + if(p) *p++ = ':'; + path=p; + } + } + } + + tryrun(pname, argv); + brk(bp); + if( errno == ENOENT || errno == 0 ) errno = besterr; + return -1; +} + +static int tryrun(pname, argv) +char * pname; +char ** argv; +{ +static char *shprog[] = {"/bin/sh", "", 0}; + struct stat st; + + if( stat(pname, &st) < 0 ) return; + if( !S_ISREG(st.st_mode) ) return; + +#ifdef __AS386_16__ + __execvve(pname, (void*)0, argv, environ); + if( errno == ENOEXEC ) + { + shprog[1] = pname; + __execvve(shprog[0], shprog, argv, environ); + } +#else + execve(pname, argv, environ); + /* FIXME - running /bin/sh in 386 mode */ +#endif +} + +#ifdef __AS386_16__ +static int +__execvve(fname, interp, argv, envp) char * fname; char ** interp; char ** argv; @@ -206,3 +289,4 @@ char ** envp; return rv; } #endif +#endif diff --git a/libc/syscall/mksys386 b/libc/syscall/mksys386 index be7b2d5..5abcbf8 100644 --- a/libc/syscall/mksys386 +++ b/libc/syscall/mksys386 @@ -50,18 +50,16 @@ awk 'BEGIN{ else if( $4 == "*" ) funcname="__" $1; else funcname=$1; - shortname=substr(funcname,1,12); - if( length(obj) > 60 ) { printf("%s\t\\\n", obj) > "syscall.mak"; obj=" "; } - obj=obj shortname ".o "; + obj=obj funcname ".o "; printf "/* CALL %s */\n\n", $0; - printf("#ifdef L_%s\n", shortname); + printf("#ifdef L_%s\n", funcname); printf("#asm\n"); printf("export _%s\n", funcname); printf("_%s:\n", funcname); @@ -86,27 +84,27 @@ awk 'BEGIN{ else { if( $3 >= 1 ) printf("#if __FIRST_ARG_IN_AX__\n"); - if( $3 >= 5 ) printf(" push edi\n"); - if( $3 >= 4 ) printf(" push esi\n"); - if( $3 >= 5 ) printf(" mov edi,[esp+16]\n"); - if( $3 >= 4 ) printf(" mov esi,[esp+12]\n"); - if( $3 >= 3 ) printf(" mov edx,[esp+8]\n"); - if( $3 >= 2 ) printf(" mov ecx,[esp+4]\n"); if( $3 >= 1 ) printf(" mov ebx,eax\n"); - if( $3 >= 1 ) printf("#else\n"); - if( $3 >= 5 ) printf(" push edi\n"); + if( $3 >= 2 ) printf(" mov ecx,[esp+4]\n"); + if( $3 >= 3 ) printf(" mov edx,[esp+8]\n"); if( $3 >= 4 ) printf(" push esi\n"); - if( $3 >= 5 ) printf(" mov edi,[esp+20]\n"); if( $3 >= 4 ) printf(" mov esi,[esp+16]\n"); - if( $3 >= 3 ) printf(" mov edx,[esp+12]\n"); - if( $3 >= 2 ) printf(" mov ecx,[esp+8]\n"); + if( $3 >= 5 ) printf(" push edi\n"); + if( $3 >= 5 ) printf(" mov edi,[esp+24]\n"); + if( $3 >= 1 ) printf("#else\n"); if( $3 >= 1 ) printf(" mov ebx,[esp+4]\n"); + if( $3 >= 2 ) printf(" mov ecx,[esp+8]\n"); + if( $3 >= 3 ) printf(" mov edx,[esp+12]\n"); + if( $3 >= 4 ) printf(" push esi\n"); + if( $3 >= 4 ) printf(" mov esi,[esp+20]\n"); + if( $3 >= 5 ) printf(" push edi\n"); + if( $3 >= 5 ) printf(" mov edi,[esp+28]\n"); if( $3 >= 1 ) printf("#endif\n"); printf(" mov eax,#%d\n", $2); printf(" int $80\n"); - if( $3 >= 4 ) printf(" pop esi\n"); if( $3 >= 5 ) printf(" pop edi\n"); + if( $3 >= 4 ) printf(" pop esi\n"); printf(" test eax,eax\n"); printf(" jl syscall_err\n"); |