summaryrefslogtreecommitdiff
path: root/tools/lib/subcmd
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/subcmd')
-rw-r--r--tools/lib/subcmd/Makefile6
-rw-r--r--tools/lib/subcmd/help.c15
-rw-r--r--tools/lib/subcmd/parse-options.c10
-rw-r--r--tools/lib/subcmd/run-command.c44
-rw-r--r--tools/lib/subcmd/subcmd-util.h2
5 files changed, 61 insertions, 16 deletions
diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile
index b87213263a5e..8703ab487b68 100644
--- a/tools/lib/subcmd/Makefile
+++ b/tools/lib/subcmd/Makefile
@@ -38,10 +38,8 @@ endif
ifeq ($(DEBUG),1)
CFLAGS += -O0
-else ifeq ($(CC_NO_CLANG), 0)
- CFLAGS += -O3
else
- CFLAGS += -O6
+ CFLAGS += -O3
endif
# Treat warnings as errors unless directed not to
@@ -76,7 +74,7 @@ include $(srctree)/tools/build/Makefile.include
all: fixdep $(LIBFILE)
-$(SUBCMD_IN): FORCE
+$(SUBCMD_IN): fixdep FORCE
@$(MAKE) $(build)=libsubcmd
$(LIBFILE): $(SUBCMD_IN)
diff --git a/tools/lib/subcmd/help.c b/tools/lib/subcmd/help.c
index 8561b0f01a24..ddaeb4eb3e24 100644
--- a/tools/lib/subcmd/help.c
+++ b/tools/lib/subcmd/help.c
@@ -9,6 +9,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
+#include <assert.h>
#include "subcmd-util.h"
#include "help.h"
#include "exec-cmd.h"
@@ -74,6 +75,9 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
size_t ci, cj, ei;
int cmp;
+ if (!excludes->cnt)
+ return;
+
ci = cj = ei = 0;
while (ci < cmds->cnt && ei < excludes->cnt) {
cmp = strcmp(cmds->names[ci]->name, excludes->names[ei]->name);
@@ -82,10 +86,11 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
ci++;
cj++;
} else {
- zfree(&cmds->names[cj]);
- cmds->names[cj++] = cmds->names[ci++];
+ cmds->names[cj++] = cmds->names[ci];
+ cmds->names[ci++] = NULL;
}
} else if (cmp == 0) {
+ zfree(&cmds->names[ci]);
ci++;
ei++;
} else if (cmp > 0) {
@@ -94,12 +99,12 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
}
if (ci != cj) {
while (ci < cmds->cnt) {
- zfree(&cmds->names[cj]);
- cmds->names[cj++] = cmds->names[ci++];
+ cmds->names[cj++] = cmds->names[ci];
+ cmds->names[ci++] = NULL;
}
}
for (ci = cj; ci < cmds->cnt; ci++)
- zfree(&cmds->names[ci]);
+ assert(cmds->names[ci] == NULL);
cmds->cnt = cj;
}
diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c
index 4b60ec03b0bb..555d617c1f50 100644
--- a/tools/lib/subcmd/parse-options.c
+++ b/tools/lib/subcmd/parse-options.c
@@ -633,10 +633,11 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
const char *const subcommands[], const char *usagestr[], int flags)
{
struct parse_opt_ctx_t ctx;
- char *buf = NULL;
/* build usage string if it's not provided */
if (subcommands && !usagestr[0]) {
+ char *buf = NULL;
+
astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]);
for (int i = 0; subcommands[i]; i++) {
@@ -678,10 +679,7 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt);
usage_with_options(usagestr, options);
}
- if (buf) {
- usagestr[0] = NULL;
- free(buf);
- }
+
return parse_options_end(&ctx);
}
@@ -809,7 +807,7 @@ static int option__cmp(const void *va, const void *vb)
static struct option *options__order(const struct option *opts)
{
int nr_opts = 0, nr_group = 0, nr_parent = 0, len;
- const struct option *o, *p = opts;
+ const struct option *o = NULL, *p = opts;
struct option *opt, *ordered = NULL, *group;
/* flatten the options that have parents */
diff --git a/tools/lib/subcmd/run-command.c b/tools/lib/subcmd/run-command.c
index 4e3a557a2f37..b7510f83209a 100644
--- a/tools/lib/subcmd/run-command.c
+++ b/tools/lib/subcmd/run-command.c
@@ -2,8 +2,10 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <ctype.h>
#include <fcntl.h>
#include <string.h>
+#include <linux/compiler.h>
#include <linux/string.h>
#include <errno.h>
#include <sys/wait.h>
@@ -215,10 +217,52 @@ static int wait_or_whine(struct child_process *cmd, bool block)
return result;
}
+/*
+ * Conservative estimate of number of characaters needed to hold an a decoded
+ * integer, assume each 3 bits needs a character byte and plus a possible sign
+ * character.
+ */
+#ifndef is_signed_type
+#define is_signed_type(type) (((type)(-1)) < (type)1)
+#endif
+#define MAX_STRLEN_TYPE(type) (sizeof(type) * 8 / 3 + (is_signed_type(type) ? 1 : 0))
+
int check_if_command_finished(struct child_process *cmd)
{
+#ifdef __linux__
+ char filename[6 + MAX_STRLEN_TYPE(typeof(cmd->pid)) + 7 + 1];
+ char status_line[256];
+ FILE *status_file;
+
+ /*
+ * Check by reading /proc/<pid>/status as calling waitpid causes
+ * stdout/stderr to be closed and data lost.
+ */
+ sprintf(filename, "/proc/%u/status", cmd->pid);
+ status_file = fopen(filename, "r");
+ if (status_file == NULL) {
+ /* Open failed assume finish_command was called. */
+ return true;
+ }
+ while (fgets(status_line, sizeof(status_line), status_file) != NULL) {
+ char *p;
+
+ if (strncmp(status_line, "State:", 6))
+ continue;
+
+ fclose(status_file);
+ p = status_line + 6;
+ while (isspace(*p))
+ p++;
+ return *p == 'Z' ? 1 : 0;
+ }
+ /* Read failed assume finish_command was called. */
+ fclose(status_file);
+ return 1;
+#else
wait_or_whine(cmd, /*block=*/false);
return cmd->finished;
+#endif
}
int finish_command(struct child_process *cmd)
diff --git a/tools/lib/subcmd/subcmd-util.h b/tools/lib/subcmd/subcmd-util.h
index dfac76e35ac7..c742b08815dc 100644
--- a/tools/lib/subcmd/subcmd-util.h
+++ b/tools/lib/subcmd/subcmd-util.h
@@ -20,8 +20,8 @@ static __noreturn inline void die(const char *err, ...)
va_start(params, err);
report(" Fatal: ", err, params);
- exit(128);
va_end(params);
+ exit(128);
}
#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })