[tip:perf/core] perf tools: Finalize subcmd independence

tip-bot for Josh Poimboeuf
2015-12-18T08:54:43Z

Commit-ID: 2f4ce5ec1d447beb42143a9653716a2ab025161e
Gitweb: http://git.kernel.org/tip/2f4ce5ec1d447beb42143a9653716a2ab025161e
Author: Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Tue, 15 Dec 2015 09:39:38 -0600
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 17 Dec 2015 14:27:10 -0300

perf tools: Finalize subcmd independence

For the files that will be moved to the subcmd library, remove all their
perf-specific includes and duplicate any needed functionality.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/6e12946f0f26ce4d543d34db68d9dae3c8551cb9.1450193761.git.jpoimboe@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/exec_cmd.c | 64 ++++++++++++++++++++++++++++++++----
tools/perf/util/help.c | 47 +++++++++++++++++++++++---
tools/perf/util/help.h | 4 ++-
tools/perf/util/pager.c | 7 +++-
tools/perf/util/parse-options.c | 73 +++++++++++++++++++++++++----------------
tools/perf/util/parse-options.h | 2 +-
tools/perf/util/run-command.c | 16 ++++++---
tools/perf/util/run-command.h | 2 ++
tools/perf/util/sigchain.c | 3 +-
tools/perf/util/subcmd-util.h | 67 +++++++++++++++++++++++++++++++++++++
tools/perf/util/util.h | 14 --------
11 files changed, 237 insertions(+), 62 deletions(-)

diff --git a/tools/perf/util/exec_cmd.c b/tools/perf/util/exec_cmd.c
index 701111a..e7f9ed79 100644
--- a/tools/perf/util/exec_cmd.c
+++ b/tools/perf/util/exec_cmd.c
@@ -1,12 +1,17 @@
-#include "cache.h"
-#include "exec_cmd.h"
-#include "quote.h"
-#include "subcmd-config.h"
-
+#include <linux/compiler.h>
+#include <linux/string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
#include "subcmd-util.h"
+#include "exec_cmd.h"
+#include "subcmd-config.h"

#define MAX_ARGS 32
+#define PATH_MAX 4096

static const char *argv_exec_path;
static const char *argv0_path;
@@ -20,6 +25,49 @@ void exec_cmd_init(const char *exec_name, const char *prefix,
subcmd_config.exec_path_env = exec_path_env;
}

+#define is_dir_sep(c) ((c) == '/')
+
+static int is_absolute_path(const char *path)
+{
+ return path[0] == '/';
+}
+
+static const char *get_pwd_cwd(void)
+{
+ static char cwd[PATH_MAX + 1];
+ char *pwd;
+ struct stat cwd_stat, pwd_stat;
+ if (getcwd(cwd, PATH_MAX) == NULL)
+ return NULL;
+ pwd = getenv("PWD");
+ if (pwd && strcmp(pwd, cwd)) {
+ stat(cwd, &cwd_stat);
+ if (!stat(pwd, &pwd_stat) &&
+ pwd_stat.st_dev == cwd_stat.st_dev &&
+ pwd_stat.st_ino == cwd_stat.st_ino) {
+ strlcpy(cwd, pwd, PATH_MAX);
+ }
+ }
+ return cwd;
+}
+
+static const char *make_nonrelative_path(const char *path)
+{
+ static char buf[PATH_MAX + 1];
+
+ if (is_absolute_path(path)) {
+ if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
+ die("Too long path: %.*s", 60, path);
+ } else {
+ const char *cwd = get_pwd_cwd();
+ if (!cwd)
+ die("Cannot determine the current working directory");
+ if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
+ die("Too long path: %.*s", 60, path);
+ }
+ return buf;
+}
+
char *system_path(const char *path)
{
char *buf = NULL;
@@ -151,8 +199,10 @@ int execl_cmd(const char *cmd,...)
break;
}
va_end(param);
- if (MAX_ARGS <= argc)
- return error("too many args to run %s", cmd);
+ if (MAX_ARGS <= argc) {
+ fprintf(stderr, " Error: too many args to run %s\n", cmd);
+ return -1;
+ }

argv[argc] = NULL;
return execv_cmd(argv);
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c
index 303a347..8169480 100644
--- a/tools/perf/util/help.c
+++ b/tools/perf/util/help.c
@@ -1,8 +1,15 @@
-#include "cache.h"
-#include "../builtin.h"
-#include "exec_cmd.h"
-#include "help.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
#include "subcmd-util.h"
+#include "help.h"
+#include "exec_cmd.h"

void add_cmdname(struct cmdnames *cmds, const char *name, size_t len)
{
@@ -70,6 +77,28 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
cmds->cnt = cj;
}

+static void get_term_dimensions(struct winsize *ws)
+{
+ char *s = getenv("LINES");
+
+ if (s != NULL) {
+ ws->ws_row = atoi(s);
+ s = getenv("COLUMNS");
+ if (s != NULL) {
+ ws->ws_col = atoi(s);
+ if (ws->ws_row && ws->ws_col)
+ return;
+ }
+ }
+#ifdef TIOCGWINSZ
+ if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
+ ws->ws_row && ws->ws_col)
+ return;
+#endif
+ ws->ws_row = 25;
+ ws->ws_col = 80;
+}
+
static void pretty_print_string_list(struct cmdnames *cmds, int longest)
{
int cols = 1, rows;
@@ -113,6 +142,14 @@ static int is_executable(const char *name)
return st.st_mode & S_IXUSR;
}

+static int has_extension(const char *filename, const char *ext)
+{
+ size_t len = strlen(filename);
+ size_t extlen = strlen(ext);
+
+ return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
+}
+
static void list_commands_in_dir(struct cmdnames *cmds,
const char *path,
const char *prefix)
@@ -168,7 +205,7 @@ void load_command_list(const char *prefix,
char *paths, *path, *colon;
path = paths = strdup(env_path);
while (1) {
- if ((colon = strchr(path, PATH_SEP)))
+ if ((colon = strchr(path, ':')))
*colon = 0;
if (!exec_path || strcmp(path, exec_path))
list_commands_in_dir(other_cmds, path, prefix);
diff --git a/tools/perf/util/help.h b/tools/perf/util/help.h
index 14851b0..096c8bc 100644
--- a/tools/perf/util/help.h
+++ b/tools/perf/util/help.h
@@ -1,12 +1,14 @@
#ifndef __PERF_HELP_H
#define __PERF_HELP_H

+#include <sys/types.h>
+
struct cmdnames {
size_t alloc;
size_t cnt;
struct cmdname {
size_t len; /* also used for similarity index in help.c */
- char name[FLEX_ARRAY];
+ char name[];
} **names;
};

diff --git a/tools/perf/util/pager.c b/tools/perf/util/pager.c
index d5ef62e..d50f3b5 100644
--- a/tools/perf/util/pager.c
+++ b/tools/perf/util/pager.c
@@ -1,4 +1,9 @@
-#include "cache.h"
+#include <sys/select.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include "pager.h"
#include "run-command.h"
#include "sigchain.h"
#include "subcmd-config.h"
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index c1da2a5..981bb44 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -1,10 +1,14 @@
-#include "util.h"
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
#include "subcmd-util.h"
#include "parse-options.h"
-#include "cache.h"
-#include "header.h"
#include "subcmd-config.h"
-#include <linux/string.h>
+#include "pager.h"

#define OPT_SHORT 1
#define OPT_UNSET 2
@@ -14,20 +18,29 @@ char *error_buf;
static int opterror(const struct option *opt, const char *reason, int flags)
{
if (flags & OPT_SHORT)
- return error("switch `%c' %s", opt->short_name, reason);
- if (flags & OPT_UNSET)
- return error("option `no-%s' %s", opt->long_name, reason);
- return error("option `%s' %s", opt->long_name, reason);
+ fprintf(stderr, " Error: switch `%c' %s", opt->short_name, reason);
+ else if (flags & OPT_UNSET)
+ fprintf(stderr, " Error: option `no-%s' %s", opt->long_name, reason);
+ else
+ fprintf(stderr, " Error: option `%s' %s", opt->long_name, reason);
+
+ return -1;
+}
+
+static const char *skip_prefix(const char *str, const char *prefix)
+{
+ size_t len = strlen(prefix);
+ return strncmp(str, prefix, len) ? NULL : str + len;
}

static void optwarning(const struct option *opt, const char *reason, int flags)
{
if (flags & OPT_SHORT)
- warning("switch `%c' %s", opt->short_name, reason);
+ fprintf(stderr, " Warning: switch `%c' %s", opt->short_name, reason);
else if (flags & OPT_UNSET)
- warning("option `no-%s' %s", opt->long_name, reason);
+ fprintf(stderr, " Warning: option `no-%s' %s", opt->long_name, reason);
else
- warning("option `%s' %s", opt->long_name, reason);
+ fprintf(stderr, " Warning: option `%s' %s", opt->long_name, reason);
}

static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
@@ -71,11 +84,11 @@ static int get_value(struct parse_opt_ctx_t *p,

if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
p->excl_opt->long_name == NULL) {
- scnprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
- p->excl_opt->short_name);
+ snprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
+ p->excl_opt->short_name);
} else {
- scnprintf(msg, sizeof(msg), "cannot be used with %s",
- p->excl_opt->long_name);
+ snprintf(msg, sizeof(msg), "cannot be used with %s",
+ p->excl_opt->long_name);
}
opterror(opt, msg, flags);
return -3;
@@ -401,14 +414,16 @@ match:
return get_value(p, options, flags);
}

- if (ambiguous_option)
- return error("Ambiguous option: %s "
- "(could be --%s%s or --%s%s)",
- arg,
- (ambiguous_flags & OPT_UNSET) ? "no-" : "",
- ambiguous_option->long_name,
- (abbrev_flags & OPT_UNSET) ? "no-" : "",
- abbrev_option->long_name);
+ if (ambiguous_option) {
+ fprintf(stderr,
+ " Error: Ambiguous option: %s (could be --%s%s or --%s%s)",
+ arg,
+ (ambiguous_flags & OPT_UNSET) ? "no-" : "",
+ ambiguous_option->long_name,
+ (abbrev_flags & OPT_UNSET) ? "no-" : "",
+ abbrev_option->long_name);
+ return -1;
+ }
if (abbrev_option)
return get_value(p, abbrev_option, abbrev_flags);
return -2;
@@ -420,7 +435,7 @@ static void check_typos(const char *arg, const struct option *options)
return;

if (!prefixcmp(arg, "no-")) {
- error ("did you mean `--%s` (with two dashes ?)", arg);
+ fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
exit(129);
}

@@ -428,7 +443,7 @@ static void check_typos(const char *arg, const struct option *options)
if (!options->long_name)
continue;
if (!prefixcmp(options->long_name, arg)) {
- error ("did you mean `--%s` (with two dashes ?)", arg);
+ fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
exit(129);
}
}
@@ -746,16 +761,18 @@ static int option__cmp(const void *va, const void *vb)

static struct option *options__order(const struct option *opts)
{
- int nr_opts = 0;
+ int nr_opts = 0, len;
const struct option *o = opts;
struct option *ordered;

for (o = opts; o->type != OPTION_END; o++)
++nr_opts;

- ordered = memdup(opts, sizeof(*o) * (nr_opts + 1));
- if (ordered == NULL)
+ len = sizeof(*o) * (nr_opts + 1);
+ ordered = malloc(len);
+ if (!ordered)
goto out;
+ memcpy(ordered, opts, len);

qsort(ordered, nr_opts, sizeof(*o), option__cmp);
out:
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index d1544069..dec893f 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -1,8 +1,8 @@
#ifndef __PERF_PARSE_OPTIONS_H
#define __PERF_PARSE_OPTIONS_H

-#include <linux/kernel.h>
#include <stdbool.h>
+#include <stdint.h>

enum parse_opt_type {
/* special types */
diff --git a/tools/perf/util/run-command.c b/tools/perf/util/run-command.c
index 910c0f6..fed37d6 100644
--- a/tools/perf/util/run-command.c
+++ b/tools/perf/util/run-command.c
@@ -1,7 +1,15 @@
-#include "cache.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include "subcmd-util.h"
#include "run-command.h"
#include "exec_cmd.h"
-#include "debug.h"
+
+#define STRERR_BUFSIZE 128

static inline void close_pair(int fd[2])
{
@@ -164,8 +172,8 @@ static int wait_or_whine(pid_t pid)
if (waiting < 0) {
if (errno == EINTR)
continue;
- error("waitpid failed (%s)",
- strerror_r(errno, sbuf, sizeof(sbuf)));
+ fprintf(stderr, " Error: waitpid failed (%s)",
+ strerror_r(errno, sbuf, sizeof(sbuf)));
return -ERR_RUN_COMMAND_WAITPID;
}
if (waiting != pid)
diff --git a/tools/perf/util/run-command.h b/tools/perf/util/run-command.h
index cf7d655..4a55393 100644
--- a/tools/perf/util/run-command.h
+++ b/tools/perf/util/run-command.h
@@ -1,6 +1,8 @@
#ifndef __PERF_RUN_COMMAND_H
#define __PERF_RUN_COMMAND_H

+#include <unistd.h>
+
enum {
ERR_RUN_COMMAND_FORK = 10000,
ERR_RUN_COMMAND_EXEC,
diff --git a/tools/perf/util/sigchain.c b/tools/perf/util/sigchain.c
index ba785e9..3537c34 100644
--- a/tools/perf/util/sigchain.c
+++ b/tools/perf/util/sigchain.c
@@ -1,5 +1,6 @@
+#include <signal.h>
+#include "subcmd-util.h"
#include "sigchain.h"
-#include "cache.h"

#define SIGCHAIN_MAX_SIGNALS 32

diff --git a/tools/perf/util/subcmd-util.h b/tools/perf/util/subcmd-util.h
index 98fb9f9..321aeb1 100644
--- a/tools/perf/util/subcmd-util.h
+++ b/tools/perf/util/subcmd-util.h
@@ -1,8 +1,66 @@
#ifndef __PERF_SUBCMD_UTIL_H
#define __PERF_SUBCMD_UTIL_H

+#include <stdarg.h>
+#include <stdlib.h>
#include <stdio.h>

+#define NORETURN __attribute__((__noreturn__))
+
+static inline void report(const char *prefix, const char *err, va_list params)
+{
+ char msg[1024];
+ vsnprintf(msg, sizeof(msg), err, params);
+ fprintf(stderr, " %s%s\n", prefix, msg);
+}
+
+static NORETURN inline void die(const char *err, ...)
+{
+ va_list params;
+
+ va_start(params, err);
+ report(" Fatal: ", err, params);
+ exit(128);
+ va_end(params);
+}
+
+#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
+
+#define alloc_nr(x) (((x)+16)*3/2)
+
+/*
+ * Realloc the buffer pointed at by variable 'x' so that it can hold
+ * at least 'nr' entries; the number of entries currently allocated
+ * is 'alloc', using the standard growing factor alloc_nr() macro.
+ *
+ * DO NOT USE any expression with side-effect for 'x' or 'alloc'.
+ */
+#define ALLOC_GROW(x, nr, alloc) \
+ do { \
+ if ((nr) > alloc) { \
+ if (alloc_nr(alloc) < (nr)) \
+ alloc = (nr); \
+ else \
+ alloc = alloc_nr(alloc); \
+ x = xrealloc((x), alloc * sizeof(*(x))); \
+ } \
+ } while(0)
+
+static inline void *xrealloc(void *ptr, size_t size)
+{
+ void *ret = realloc(ptr, size);
+ if (!ret && !size)
+ ret = realloc(ptr, 1);
+ if (!ret) {
+ ret = realloc(ptr, size);
+ if (!ret && !size)
+ ret = realloc(ptr, 1);
+ if (!ret)
+ die("Out of memory, realloc failed");
+ }
+ return ret;
+}
+
#define astrcatf(out, fmt, ...) \
({ \
char *tmp = *(out); \
@@ -21,4 +79,13 @@ static inline void astrcat(char **out, const char *add)
free(tmp);
}

+static inline int prefixcmp(const char *str, const char *prefix)
+{
+ for (; ; str++, prefix++)
+ if (!*prefix)
+ return 0;
+ else if (*str != *prefix)
+ return (unsigned char)*prefix - (unsigned char)*str;
+}
+
#endif /* __PERF_SUBCMD_UTIL_H */
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 150858f..4b519c5 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -151,12 +151,6 @@ extern void set_warning_routine(void (*routine)(const char *err, va_list params)
extern int prefixcmp(const char *str, const char *prefix);
extern void set_buildid_dir(const char *dir);

-static inline const char *skip_prefix(const char *str, const char *prefix)
-{
- size_t len = strlen(prefix);
- return strncmp(str, prefix, len) ? NULL : str + len;
-}
-
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 1)
#define HAVE_STRCHRNUL
@@ -187,14 +181,6 @@ static inline void *zalloc(size_t size)

#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })

-static inline int has_extension(const char *filename, const char *ext)
-{
- size_t len = strlen(filename);
- size_t extlen = strlen(ext);
-
- return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
-}
-
/* Sane ctype - no locale, and works with signed chars */
#undef isascii
#undef isspace