📄 _exec.c
字号:
#include <lib.h>#define execl _execl#define execle _execle#define execv _execv#define execve _execve#define sbrk _sbrk#include <minix/minlib.h>#include <stdarg.h>#include <string.h>#include <unistd.h>extern char **environ;#define PTRSIZE (sizeof(char *))#ifdef _ANSIPUBLIC int execl(const char *name, const char *arg, ...)#elsePUBLIC int execl(name)char *name;#endif{ va_list argp; int result; va_start(argp, name); /* The following cast of argp is not portable. Doing it right by copying * the args to a true array will cost as much as ARG_MAX bytes of space. */ result = execve(name, (char **) argp, environ); va_end(argp); return(result);}#ifdef _ANSIPUBLIC int execle(const char *name, const char *arg, ...)#elsePUBLIC int execle(name)char *name;#endif{ va_list argp; char **p; int result; va_start(argp, name); /* The following cast of argp is not portable, as for execl(). */ p = (char **) argp; while (*p++ != NIL_PTR) ; /* null statement */ result = execve(name, (char **) argp, (char **) *p); va_end(argp); return(result);}PUBLIC int execv(name, argv)_CONST char *name;char * _CONST argv[];{ return(execve(name, argv, environ));}PUBLIC int execve(path, argv, envp)_CONST char *path; /* pointer to name of file to be executed */char * _CONST argv[]; /* pointer to argument array */char * _CONST envp[]; /* pointer to environment */{ int i, j; /* Count the argument pointers and environment pointers. */ i = 0; if (argv != NULL) { while (argv[i] != NULL) i++; } j = 0; if (envp != NULL) { while (envp[j] != NULL) j++; } return(__execve(path, argv, envp, i, j));}PUBLIC int __execve(path, argv, envp, nargs, nenvps)_CONST char *path; /* pointer to name of file to be executed */char * _CONST argv[]; /* pointer to argument array */char * _CONST envp[]; /* pointer to environment */int nargs; /* number of args */int nenvps; /* number of environment strings */{/* This is split off from execve to be called from execvp, so execvp does not * have to allocate up to ARG_MAX bytes just to prepend "sh" to the arg array. */ char *hp, **ap, *p; int i, stackbytes, npointers, overflow, temp; char *stack; message m; /* Decide how big a stack is needed. Be paranoid about overflow. */ overflow = FALSE; npointers = 1 + nargs + 1 + nenvps + 1; /* 1's for argc and NULLs */ stackbytes = nargs + nenvps; /* 1 byte for each null in strings */ if (nargs < 0 || nenvps < 0 || stackbytes < nargs || npointers < stackbytes) overflow = TRUE; for (i = PTRSIZE; i != 0; i--) { temp = stackbytes + npointers; if (temp < stackbytes) overflow = TRUE; stackbytes = temp; } ap = (char **) argv; for (i = 0; i < nargs; i++) { temp = stackbytes + strlen(*ap++); if (temp < stackbytes) overflow = TRUE; stackbytes = temp; } ap = (char **) envp; for (i = 0; i < nenvps; i++) { temp = stackbytes + strlen(*ap++); if (temp < stackbytes) overflow = TRUE; stackbytes = temp; } temp = stackbytes + PTRSIZE - 1; if (temp < stackbytes) overflow = TRUE; stackbytes = (temp / PTRSIZE) * PTRSIZE; /* Check for overflow before committing sbrk. */ if (overflow) { errno = E2BIG; return(-1); } /* Allocate the stack. */ stack = sbrk(stackbytes); if (stack == (char *) -1) { errno = E2BIG; return(-1); } /* Prepare the stack vector and argc. */ ap = (char **) stack; hp = &stack[npointers * PTRSIZE]; *ap++ = (char *) nargs; /* Prepare the argument pointers and strings. */ for (i = 0; i < nargs; i++) { *ap++ = (char *) (hp - stack); p = *argv++; while ( (*hp++ = *p++) != 0) ; } *ap++ = (char *) NULL; /* Prepare the environment pointers and strings. */ for (i = 0; i < nenvps; i++) { *ap++ = (char *) (hp - stack); p = *envp++; while ( (*hp++ = *p++) != 0) ; } *ap++ = (char *) NULL; /* Do the real work. */ m.m1_i1 = strlen(path) + 1; m.m1_i2 = stackbytes; m.m1_p1 = (char *) path; m.m1_p2 = stack; (void) _syscall(MM, EXEC, &m); /* The exec failed. */ sbrk(-stackbytes); return(m.m_type);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -