exec_cmd.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "cache.h"
  2. #include "exec_cmd.h"
  3. #include "quote.h"
  4. #include <string.h>
  5. #define MAX_ARGS 32
  6. static const char *argv_exec_path;
  7. static const char *argv0_path;
  8. const char *system_path(const char *path)
  9. {
  10. #ifdef RUNTIME_PREFIX
  11. static const char *prefix;
  12. #else
  13. static const char *prefix = PREFIX;
  14. #endif
  15. struct strbuf d = STRBUF_INIT;
  16. if (is_absolute_path(path))
  17. return path;
  18. #ifdef RUNTIME_PREFIX
  19. assert(argv0_path);
  20. assert(is_absolute_path(argv0_path));
  21. if (!prefix &&
  22. !(prefix = strip_path_suffix(argv0_path, PERF_EXEC_PATH)) &&
  23. !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
  24. !(prefix = strip_path_suffix(argv0_path, "perf"))) {
  25. prefix = PREFIX;
  26. fprintf(stderr, "RUNTIME_PREFIX requested, "
  27. "but prefix computation failed. "
  28. "Using static fallback '%s'.\n", prefix);
  29. }
  30. #endif
  31. strbuf_addf(&d, "%s/%s", prefix, path);
  32. path = strbuf_detach(&d, NULL);
  33. return path;
  34. }
  35. const char *perf_extract_argv0_path(const char *argv0)
  36. {
  37. const char *slash;
  38. if (!argv0 || !*argv0)
  39. return NULL;
  40. slash = argv0 + strlen(argv0);
  41. while (argv0 <= slash && !is_dir_sep(*slash))
  42. slash--;
  43. if (slash >= argv0) {
  44. argv0_path = xstrndup(argv0, slash - argv0);
  45. return slash + 1;
  46. }
  47. return argv0;
  48. }
  49. void perf_set_argv_exec_path(const char *exec_path)
  50. {
  51. argv_exec_path = exec_path;
  52. /*
  53. * Propagate this setting to external programs.
  54. */
  55. setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
  56. }
  57. /* Returns the highest-priority, location to look for perf programs. */
  58. const char *perf_exec_path(void)
  59. {
  60. const char *env;
  61. if (argv_exec_path)
  62. return argv_exec_path;
  63. env = getenv(EXEC_PATH_ENVIRONMENT);
  64. if (env && *env) {
  65. return env;
  66. }
  67. return system_path(PERF_EXEC_PATH);
  68. }
  69. static void add_path(struct strbuf *out, const char *path)
  70. {
  71. if (path && *path) {
  72. if (is_absolute_path(path))
  73. strbuf_addstr(out, path);
  74. else
  75. strbuf_addstr(out, make_nonrelative_path(path));
  76. strbuf_addch(out, PATH_SEP);
  77. }
  78. }
  79. void setup_path(void)
  80. {
  81. const char *old_path = getenv("PATH");
  82. struct strbuf new_path = STRBUF_INIT;
  83. add_path(&new_path, perf_exec_path());
  84. add_path(&new_path, argv0_path);
  85. if (old_path)
  86. strbuf_addstr(&new_path, old_path);
  87. else
  88. strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
  89. setenv("PATH", new_path.buf, 1);
  90. strbuf_release(&new_path);
  91. }
  92. const char **prepare_perf_cmd(const char **argv)
  93. {
  94. int argc;
  95. const char **nargv;
  96. for (argc = 0; argv[argc]; argc++)
  97. ; /* just counting */
  98. nargv = malloc(sizeof(*nargv) * (argc + 2));
  99. nargv[0] = "perf";
  100. for (argc = 0; argv[argc]; argc++)
  101. nargv[argc + 1] = argv[argc];
  102. nargv[argc + 1] = NULL;
  103. return nargv;
  104. }
  105. int execv_perf_cmd(const char **argv) {
  106. const char **nargv = prepare_perf_cmd(argv);
  107. /* execvp() can only ever return if it fails */
  108. execvp("perf", (char **)nargv);
  109. free(nargv);
  110. return -1;
  111. }
  112. int execl_perf_cmd(const char *cmd,...)
  113. {
  114. int argc;
  115. const char *argv[MAX_ARGS + 1];
  116. const char *arg;
  117. va_list param;
  118. va_start(param, cmd);
  119. argv[0] = cmd;
  120. argc = 1;
  121. while (argc < MAX_ARGS) {
  122. arg = argv[argc++] = va_arg(param, char *);
  123. if (!arg)
  124. break;
  125. }
  126. va_end(param);
  127. if (MAX_ARGS <= argc)
  128. return error("too many args to run %s", cmd);
  129. argv[argc] = NULL;
  130. return execv_perf_cmd(argv);
  131. }