From 00d4b0f7cf6742a66f2bac262d5a3b3a9d0cc275 Mon Sep 17 00:00:00 2001 From: Bert Date: Thu, 3 Mar 2011 10:52:16 +0100 Subject: [PATCH] Use "/bin/sh -c" for external commands --- Makefile | 2 +- commands.h | 28 ++++--------------- main.c | 82 ++++++++++++++++++++++++++++-------------------------- 3 files changed, 49 insertions(+), 63 deletions(-) diff --git a/Makefile b/Makefile index c49d2ee..e3882bc 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ all: sxiv -VERSION=git-20110301 +VERSION=git-20110303 CC?=gcc PREFIX?=/usr/local diff --git a/commands.h b/commands.h index d455fac..cb14fe6 100644 --- a/commands.h +++ b/commands.h @@ -1,29 +1,13 @@ -#define FILENAME (const char*) 0x1 - typedef struct { KeySym ksym; - const char **cmdline; Bool reload; + const char *cmdline; } command_t; -static const char *cmdline_1[] = { - "jpegtran", "-rotate", "270", "-copy", "all", "-outfile", FILENAME, - FILENAME, NULL }; - -static const char *cmdline_2[] = { - "jpegtran", "-rotate", "90", "-copy", "all", "-outfile", FILENAME, - FILENAME, NULL }; - -static const char *cmdline_3[] = { - "mogrify", "-rotate", "-90", FILENAME, NULL }; - -static const char *cmdline_4[] = { - "mogrify", "-rotate", "+90", FILENAME, NULL }; - static command_t commands[] = { - /* key command-line reload? */ - { XK_a, cmdline_1, True }, - { XK_s, cmdline_2, True }, - { XK_A, cmdline_3, True }, - { XK_S, cmdline_4, True }, + /* key reload? command, '#' is replaced by filename */ + { XK_a, True, "jpegtran -rotate 270 -copy all -outfile # #" }, + { XK_s, True, "jpegtran -rotate 90 -copy all -outfile # #" }, + { XK_A, True, "mogrify -rotate -90 #" }, + { XK_S, True, "mogrify -rotate +90 #" } }; diff --git a/main.c b/main.c index e3a1fa2..d736d12 100644 --- a/main.c +++ b/main.c @@ -273,57 +273,59 @@ void read_dir_rec(const char *dirname) { free(dirnames); } -int run_command(const char **cmdline, Bool reload) { - int argc, i; - const char **argv; +int run_command(const char *cline, Bool reload) { + int fncnt, fnlen; + char *cn, *cmdline; + const char *co, *fname; pid_t pid; - int error, ret, status; + int ret, status; - if (!cmdline) + if (!cline || !*cline) return 0; - argc = 1; - while (cmdline[argc-1]) - ++argc; + fncnt = 0; + co = cline - 1; + while ((co = strchr(co + 1, '#'))) + ++fncnt; - if (argc < 2) + if (!fncnt) return 0; - argv = (const char**) s_malloc(argc * sizeof(const char*)); - error = ret = 0; + ret = 0; + fname = filenames[mode == MODE_NORMAL ? fileidx : tns.sel]; + fnlen = strlen(fname); + cn = cmdline = (char*) s_malloc((strlen(cline) + fncnt * (fnlen + 2)) * + sizeof(char)); - for (i = 0; i < argc; ++i) { - if (cmdline[i] != FILENAME) - argv[i] = cmdline[i]; - else - argv[i] = filenames[mode == MODE_NORMAL ? fileidx : tns.sel]; - } - - if ((pid = fork()) == 0) { - execvp(argv[0], (char **const) argv); - warn("could not exec %s", argv[0]); - exit(1); - } else if (pid < 0 && !options->quiet) { - warn("could not fork. command line was:"); - error = 1; - } else if (reload) { - waitpid(pid, &status, 0); - if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { - ret = 1; - } else if (!options->quiet) { - warn("child exited with non-zero return value: %d. command line was:", - WEXITSTATUS(status)); - error = 1; + /* replace all '#' with filename */ + for (co = cline; *co; ++co) { + if (*co == '#') { + *cn++ = '"'; + strcpy(cn, fname); + cn += fnlen; + *cn++ = '"'; + } else { + *cn++ = *co; } } - - if (error) { - for (i = 0; i < argc && argv[i]; ++i) - fprintf(stderr, "%s%s", i > 0 ? " " : "", argv[i]); - fprintf(stderr, "\n"); - } + *cn = '\0'; - free(argv); + if ((pid = fork()) == 0) { + execlp("/bin/sh", "/bin/sh", "-c", cmdline, NULL); + warn("could not exec: /bin/sh"); + exit(1); + } else if (pid < 0) { + warn("could not fork. command line was: %s", cmdline); + } else if (reload) { + waitpid(pid, &status, 0); + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) + ret = 1; + else + warn("child exited with non-zero return value: %d. command line was: %s", + WEXITSTATUS(status), cmdline); + } + + free(cmdline); return ret; }