20 "perf [--version] [--help] COMMAND [ARGS]";
23 "See 'perf help COMMAND' for more information on a specific command.";
26 static int use_pager = -1;
58 #ifdef LIBAUDIT_SUPPORT
69 static int pager_command_config(
const char *var,
const char *
value,
void *
data)
87 static int tui_command_config(
const char *var,
const char *
value,
void *
data)
96 static int check_tui_config(
const char *
cmd)
105 static void commit_pager_choice(
void)
109 setenv(
"PERF_PAGER",
"cat", 1);
119 static int handle_options(
const char ***argv,
int *
argc,
int *envchanged)
124 const char *
cmd = (*argv)[0];
133 if (!
strcmp(cmd,
"--help") || !
strcmp(cmd,
"--version"))
147 }
else if (!
strcmp(cmd,
"--html-path")) {
150 }
else if (!
strcmp(cmd,
"-p") || !
strcmp(cmd,
"--paginate")) {
152 }
else if (!
strcmp(cmd,
"--no-pager")) {
156 }
else if (!
strcmp(cmd,
"--perf-dir")) {
158 fprintf(stderr,
"No directory given for --perf-dir.\n");
171 }
else if (!
strcmp(cmd,
"--work-tree")) {
173 fprintf(stderr,
"No directory given for --work-tree.\n");
185 }
else if (!
strcmp(cmd,
"--debugfs-dir")) {
187 fprintf(stderr,
"No directory given for --debugfs-dir.\n");
200 }
else if (!
strcmp(cmd,
"--list-cmds")) {
209 fprintf(stderr,
"Unknown option: %s\n", cmd);
220 static int handle_alias(
int *argcp,
const char ***argv)
223 int count, option_count;
224 const char **new_argv;
225 const char *alias_command;
228 alias_command = (*argv)[0];
231 if (alias_string[0] ==
'!') {
236 strbuf_addstr(&
buf, alias_string);
239 alias_string =
buf.buf;
242 if (
ret >= 0 && WIFEXITED(
ret) &&
243 WEXITSTATUS(
ret) != 127)
245 die(
"Failed to run '%s' when expanding alias '%s'",
246 alias_string + 1, alias_command);
250 die(
"Bad alias.%s string", alias_command);
251 option_count = handle_options(&new_argv, &count, &envchanged);
253 die(
"alias '%s' changes environment variables\n"
254 "You can use '!perf' in the alias to do this.",
256 memmove(new_argv - option_count, new_argv,
257 count *
sizeof(
char *));
258 new_argv -= option_count;
261 die(
"empty alias for %s", alias_command);
263 if (!
strcmp(alias_command, new_argv[0]))
264 die(
"recursive alias: %s", alias_command);
266 new_argv = realloc(new_argv,
sizeof(
char *) *
267 (count + *argcp + 1));
269 memcpy(new_argv + count, *argv + 1,
sizeof(
char *) * *argcp);
270 new_argv[count + *argcp] =
NULL;
285 #define RUN_SETUP (1<<0)
286 #define USE_PAGER (1<<1)
291 #define NEED_WORK_TREE (1<<2)
293 static int run_builtin(
struct cmd_struct *
p,
int argc,
const char **argv)
310 commit_pager_choice();
312 status = p->
fn(argc, argv, prefix);
316 return status & 0xff;
319 if (fstat(fileno(stdout), &st))
329 die(
"unknown write failure on standard output");
335 static void handle_internal_command(
int argc,
const char **argv)
337 const char *cmd = argv[0];
341 if (
sizeof(ext) > 1) {
343 if (i > 0 && !
strcmp(argv[0] + i, ext)) {
344 char *argv0 = strdup(argv[0]);
345 argv[0] = cmd = argv0;
351 if (argc > 1 && !
strcmp(argv[1],
"--help")) {
353 argv[0] = cmd =
"help";
360 exit(run_builtin(p, argc, argv));
364 static void execv_dashed_external(
const char **argv)
388 die(
"unable to run '%s'", argv[0]);
398 static int run_argv(
int *argcp,
const char ***argv)
404 handle_internal_command(*argcp, *argv);
407 execv_dashed_external(*argv);
413 if (done_alias || !handle_alias(argcp, argv))
421 static void pthread__block_sigwinch(
void)
439 int main(
int argc,
const char **argv)
461 handle_internal_command(argc, argv);
462 die(
"cannot handle %s internally", cmd);
468 handle_options(&argv, &argc,
NULL);
469 commit_pager_choice();
496 pthread__block_sigwinch();
499 static int done_help;
500 static int was_alias;
502 was_alias = run_argv(&argc, &argv);
507 fprintf(stderr,
"Expansion of alias '%s' failed; "
508 "'%s' is not a perf-command\n",
519 fprintf(stderr,
"Failed to run command '%s': %s\n",