Added execprog() and execprogl(), which are safer alternatives to system(3)
authormarkus schnalke <meillo@marmaro.de>
Wed, 14 Jan 2015 06:28:33 +0000 (07:28 +0100)
committermarkus schnalke <meillo@marmaro.de>
Wed, 14 Jan 2015 06:28:33 +0000 (07:28 +0100)
This is motivated by the currently failing test case
tests/whatnow/test-attach-detach.

h/prototypes.h
sbr/Makefile.in
sbr/execprog.c [new file with mode: 0644]

index 26981f8..1333a84 100644 (file)
@@ -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 *);
index 64ecb9e..9729346 100644 (file)
@@ -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 (file)
index 0000000..6a4a912
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+** execprog.c -- invoke an external command synchronously
+**               This is a safer alternative to system(3)
+*/
+
+#include <h/mh.h>
+
+
+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;
+}