/* * exec.c:: various execXX emulations. If we're in a child that has been * forked, then we restore our parent's data area and shrink the * fork information block to the minimum. If we're not in any child, then * we just wing it (we probably should shrink the text+data+bss block to * give more room, but that would be rather difficult to do properly). * * the real work is done in spawnve.c. */ #include #include #include #include #include #include extern int _x_Bit_set_in_stat; /* in stat.c */ int execve(path, argv, envp) char *path, **argv, **envp; { int savex = _x_Bit_set_in_stat; /* check to make sure that the file is executable. alas, this is not foolproof, since .g and .sh files are marked as executable even though they're not, really. */ _x_Bit_set_in_stat = 1; if (access(path, X_OK)) { _x_Bit_set_in_stat = savex; return -1; } _x_Bit_set_in_stat = savex; /* * the call to spawnve shouldn't return unless there is an error */ return spawnve(P_OVERLAY, path, argv, envp); } int execv(path, argv) char *path, **argv; { return execve(path, argv, (char **)0); } int execvp(name, argv) char *name; char **argv; { /* note: we cannot check x bit here as we dont know the full path. * we flag spawnvp to do this by passing it -ve mode */ return spawnvp(-P_OVERLAY, name, argv); } #ifdef __STDC__ int execl(char *path, ...) #else int execl(path) char *path; #endif { va_list args; va_start(args, path); return execve(path, (char **)args, (char **)0); }