3
0

execable.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Utility routines.
  4. *
  5. * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. #include "libbb.h"
  10. /* check if path points to an executable file;
  11. * return 1 if found;
  12. * return 0 otherwise;
  13. */
  14. int FAST_FUNC execable_file(const char *name)
  15. {
  16. struct stat s;
  17. return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode));
  18. }
  19. /* search (*PATHp) for an executable file;
  20. * return allocated string containing full path if found;
  21. * PATHp points to the component after the one where it was found
  22. * (or NULL),
  23. * you may call find_execable again with this PATHp to continue
  24. * (if it's not NULL).
  25. * return NULL otherwise; (PATHp is undefined)
  26. * in all cases (*PATHp) contents will be trashed (s/:/NUL/).
  27. */
  28. char* FAST_FUNC find_execable(const char *filename, char **PATHp)
  29. {
  30. char *p, *n;
  31. p = *PATHp;
  32. while (p) {
  33. n = strchr(p, ':');
  34. if (n)
  35. *n++ = '\0';
  36. if (*p != '\0') { /* it's not a PATH="foo::bar" situation */
  37. p = concat_path_file(p, filename);
  38. if (execable_file(p)) {
  39. *PATHp = n;
  40. return p;
  41. }
  42. free(p);
  43. }
  44. p = n;
  45. } /* on loop exit p == NULL */
  46. return p;
  47. }
  48. /* search $PATH for an executable file;
  49. * return 1 if found;
  50. * return 0 otherwise;
  51. */
  52. int FAST_FUNC exists_execable(const char *filename)
  53. {
  54. char *path = xstrdup(getenv("PATH"));
  55. char *tmp = path;
  56. char *ret = find_execable(filename, &tmp);
  57. free(path);
  58. if (ret) {
  59. free(ret);
  60. return 1;
  61. }
  62. return 0;
  63. }
  64. #if ENABLE_FEATURE_PREFER_APPLETS
  65. /* just like the real execvp, but try to launch an applet named 'file' first */
  66. int FAST_FUNC BB_EXECVP(const char *file, char *const argv[])
  67. {
  68. if (find_applet_by_name(file) >= 0)
  69. execvp(bb_busybox_exec_path, argv);
  70. return execvp(file, argv);
  71. }
  72. #endif
  73. int FAST_FUNC BB_EXECVP_or_die(char **argv)
  74. {
  75. BB_EXECVP(argv[0], argv);
  76. /* SUSv3-mandated exit codes */
  77. xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
  78. bb_perror_msg_and_die("can't execute '%s'", argv[0]);
  79. }