From 815b63fd3a630eb462e7ab9d8af09f19e129a5af Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 9 May 2017 21:04:11 -0400 Subject: Implement -D exec --- exec.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index e28b4fc..5f3a804 100644 --- a/exec.c +++ b/exec.c @@ -10,6 +10,7 @@ *********************************************************************/ #include "exec.h" +#include "bfs.h" #include "bftw.h" #include "color.h" #include "dstring.h" @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +27,28 @@ #include #include +/** Print some debugging info. */ +static void bfs_exec_debug(const struct bfs_exec *execbuf, const char *format, ...) { + if (!(execbuf->flags & BFS_EXEC_DEBUG)) { + return; + } + + if (execbuf->flags & BFS_EXEC_CONFIRM) { + fputs("-ok", stderr); + } else { + fputs("-exec", stderr); + } + if (execbuf->flags & BFS_EXEC_CHDIR) { + fputs("dir", stderr); + } + fputs(": ", stderr); + + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); +} + extern char **environ; /** Determine the size of a single argument, for comparison to arg_max. */ @@ -38,14 +62,17 @@ static size_t bfs_exec_arg_size(const char *arg) { /** Determine the maximum argv size. */ static size_t bfs_exec_arg_max(const struct bfs_exec *execbuf) { long arg_max = sysconf(_SC_ARG_MAX); + bfs_exec_debug(execbuf, "ARG_MAX: %ld according to sysconf()\n", arg_max); if (arg_max < 0) { arg_max = BFS_EXEC_ARG_MAX; + bfs_exec_debug(execbuf, "ARG_MAX: %ld assumed\n", arg_max); } // We have to share space with the environment variables for (char **envp = environ; *envp; ++envp) { arg_max -= bfs_exec_arg_size(*envp); } + bfs_exec_debug(execbuf, "ARG_MAX: %ld remaining after environment variables\n", arg_max); // Account for the non-placeholder arguments for (size_t i = 0; i < execbuf->placeholder; ++i) { @@ -54,9 +81,11 @@ static size_t bfs_exec_arg_max(const struct bfs_exec *execbuf) { for (size_t i = execbuf->placeholder + 1; i < execbuf->tmpl_argc; ++i) { arg_max -= bfs_exec_arg_size(execbuf->tmpl_argv[i]); } + bfs_exec_debug(execbuf, "ARG_MAX: %ld remaining after fixed arguments\n", arg_max); // POSIX recommends subtracting 2048, for some wiggle room arg_max -= 2048; + bfs_exec_debug(execbuf, "ARG_MAX: %ld remaining after headroom\n", arg_max); if (arg_max < 0) { arg_max = 0; @@ -64,10 +93,13 @@ static size_t bfs_exec_arg_max(const struct bfs_exec *execbuf) { arg_max = BFS_EXEC_ARG_MAX; } + bfs_exec_debug(execbuf, "ARG_MAX: %ld final value\n", arg_max); return arg_max; } -struct bfs_exec *parse_bfs_exec(char **argv, enum bfs_exec_flags flags, CFILE *cerr) { +struct bfs_exec *parse_bfs_exec(char **argv, enum bfs_exec_flags flags, const struct cmdline *cmdline) { + CFILE *cerr = cmdline->cerr; + struct bfs_exec *execbuf = malloc(sizeof(*execbuf)); if (!execbuf) { perror("malloc()"); @@ -86,6 +118,10 @@ struct bfs_exec *parse_bfs_exec(char **argv, enum bfs_exec_flags flags, CFILE *c execbuf->wd_len = 0; execbuf->ret = 0; + if (cmdline->debug & DEBUG_EXEC) { + execbuf->flags |= BFS_EXEC_DEBUG; + } + size_t i; const char *arg; for (i = 1, arg = argv[i]; arg; arg = argv[++i]) { @@ -319,6 +355,8 @@ static int bfs_exec_spawn(const struct bfs_exec *execbuf) { } } + bfs_exec_debug(execbuf, "Executing '%s' ... [%zu arguments]\n", execbuf->argv[0], execbuf->argc - 1); + pid_t pid = fork(); if (pid < 0) { @@ -425,15 +463,15 @@ static int bfs_exec_flush(struct bfs_exec *execbuf) { /** Check if a flush is needed before a new file is processed. */ static bool bfs_exec_needs_flush(struct bfs_exec *execbuf, const struct BFTW *ftwbuf, const char *arg) { if (execbuf->flags & BFS_EXEC_CHDIR) { - if (ftwbuf->nameoff > execbuf->wd_len) { - return true; - } - if (execbuf->wd_path && strncmp(ftwbuf->path, execbuf->wd_path, execbuf->wd_len) != 0) { + if (ftwbuf->nameoff > execbuf->wd_len + || (execbuf->wd_path && strncmp(ftwbuf->path, execbuf->wd_path, execbuf->wd_len) != 0)) { + bfs_exec_debug(execbuf, "Changed directories, executing buffered command\n"); return true; } } if (execbuf->arg_size + bfs_exec_arg_size(arg) > execbuf->arg_max) { + bfs_exec_debug(execbuf, "Reached max command size, executing buffered command\n"); return true; } @@ -518,6 +556,7 @@ int bfs_exec(struct bfs_exec *execbuf, const struct BFTW *ftwbuf) { int bfs_exec_finish(struct bfs_exec *execbuf) { if (execbuf->flags & BFS_EXEC_MULTI) { + bfs_exec_debug(execbuf, "Finishing execution, executing buffered command\n"); if (bfs_exec_flush(execbuf) != 0) { execbuf->ret = -1; } -- cgit v1.2.3