From 0127c00f735b9e38608676b9f7bd3c6e38a7ffb4 Mon Sep 17 00:00:00 2001 From: markus schnalke Date: Wed, 14 Jan 2015 07:28:33 +0100 Subject: [PATCH] Added execprog() and execprogl(), which are safer alternatives to system(3) This is motivated by the currently failing test case tests/whatnow/test-attach-detach. --- h/prototypes.h | 2 ++ sbr/Makefile.in | 2 +- sbr/execprog.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 sbr/execprog.c diff --git a/h/prototypes.h b/h/prototypes.h index 26981f8..1333a84 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -40,6 +40,8 @@ void cpydgst(int, int, char *, char *); int decode_rfc2047(char *, char *, size_t); void discard(FILE *); int default_done(int); +int execprog(char *, char **); +int execprogl(char *, char *, ...); char *expandfol(char *); char *expanddir(char *); int ext_hook(char *, char *, char *); diff --git a/sbr/Makefile.in b/sbr/Makefile.in index 64ecb9e..9729346 100644 --- a/sbr/Makefile.in +++ b/sbr/Makefile.in @@ -51,7 +51,7 @@ SRCS = addrsbr.c ambigsw.c brkstring.c \ context_replace.c context_save.c \ cpydata.c cpydgst.c crawl_folders.c \ discard.c done.c dtime.c dtimep.c \ - error.c ext_hook.c folder_addmsg.c folder_delmsgs.c \ + error.c execprog.c ext_hook.c folder_addmsg.c folder_delmsgs.c \ folder_free.c folder_read.c \ folder_realloc.c gans.c getans.c getanswer.c \ getarguments.c getcpy.c \ diff --git a/sbr/execprog.c b/sbr/execprog.c new file mode 100644 index 0000000..6a4a912 --- /dev/null +++ b/sbr/execprog.c @@ -0,0 +1,58 @@ +/* +** execprog.c -- invoke an external command synchronously +** This is a safer alternative to system(3) +*/ + +#include + + +int +execprog(char *cmd, char **arg) +{ + pid_t pid; + + context_save(); + fflush(stdout); + + switch (pid = fork()) { + case -1: + /* fork error */ + advise("fork", "unable to"); + return 1; + + case 0: + /* child */ + execvp(cmd, arg); + fprintf(stderr, "unable to exec "); + perror(cmd); + _exit(-1); + + default: + /* parent */ + return (pidwait(pid, -1) & 0377 ? 1 : 0); + } + + return 1; /* NOT REACHED */ +} + + +int +execprogl(char *cmd, char *arg, ...) +{ + va_list ap; + int argc = 0; + char *argv[MAXARGS]; + char *cp; + int ret; + + argv[argc++] = mhbasename(arg); + va_start(ap, arg); + while ((cp = va_arg(ap, char *))) { + argv[argc++] = cp; + } + argv[argc] = NULL; + ret = execprog(cmd, argv); + va_end(ap); + + return ret; +} -- 1.7.10.4