execable.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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 tarball for details.
  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. */
  67. int FAST_FUNC bb_execvp(const char *file, char *const argv[])
  68. {
  69. return execvp(find_applet_by_name(file) >= 0 ? bb_busybox_exec_path : file,
  70. argv);
  71. }
  72. #endif