execvp.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #include <stdio.h>
  2. #include <syscall.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <sys/stat.h>
  7. extern char ** environ;
  8. extern char * _argv_0;
  9. extern int __libc_debug;
  10. #define DEFAULT_PATH "/bin:/usr/bin"
  11. int execve(const char *name, char * const argv[], char * const envp[]) {
  12. if (__libc_debug) {
  13. fprintf(stderr, "%s: execve(\"%s\"", _argv_0, name);
  14. char * const* arg = argv;
  15. while (*arg) {
  16. fprintf(stderr,", \"%s\"", *arg);
  17. arg++;
  18. }
  19. fprintf(stderr, ")\n");
  20. }
  21. __sets_errno(syscall_execve((char*)name,(char**)argv,(char**)envp));
  22. }
  23. int execvp(const char *file, char *const argv[]) {
  24. if (file && (!strstr(file, "/"))) {
  25. /* We don't quite understand "$PATH", so... */
  26. char * path = getenv("PATH");
  27. if (!path) {
  28. path = DEFAULT_PATH;
  29. }
  30. char * xpath = strdup(path);
  31. char * p, * last;
  32. for ((p = strtok_r(xpath, ":", &last)); p; p = strtok_r(NULL, ":", &last)) {
  33. int r;
  34. struct stat stat_buf;
  35. char * exe = malloc(strlen(p) + strlen(file) + 2);
  36. strcpy(exe, p);
  37. strcat(exe, "/");
  38. strcat(exe, file);
  39. r = stat(exe, &stat_buf);
  40. if (r != 0) {
  41. continue;
  42. }
  43. if (!(stat_buf.st_mode & 0111)) {
  44. continue; /* XXX not technically correct; need to test perms */
  45. }
  46. return execve(exe, argv, environ);
  47. }
  48. free(xpath);
  49. errno = ENOENT;
  50. return -1;
  51. } else if (file) {
  52. return execve(file, argv, environ);
  53. }
  54. errno = ENOENT;
  55. return -1;
  56. }
  57. int execv(const char * file, char * const argv[]) {
  58. return execve(file, argv, environ);
  59. }