From 81a17ab471944888106c70a719e99d6e6ba96f22 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 10 Apr 2004 14:43:55 +0000 Subject: [PATCH] Added a couple of functions for running of external commands with error checking. A nice replacement for system(). --- lib/runcmd.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 lib/runcmd.c diff --git a/lib/runcmd.c b/lib/runcmd.c new file mode 100644 index 00000000..df44f7d3 --- /dev/null +++ b/lib/runcmd.c @@ -0,0 +1,119 @@ +/* + * Sherlock Library -- Running of Commands + * + * (c) 2004 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include "lib/lib.h" + +#include +#include +#include +#include +#include + +void NONRET +exec_command_v(byte *cmd, va_list args) +{ + va_list cargs = args; + int cnt = 2; + byte *arg; + while (arg = va_arg(cargs, byte *)) + cnt++; + char **argv = alloca(sizeof(byte *) * cnt); + argv[0] = cmd; + cnt = 1; + cargs = args; + while (arg = va_arg(cargs, byte *)) + argv[cnt++] = arg; + argv[cnt] = NULL; + execv(cmd, argv); + byte echo[256]; + echo_command_v(echo, sizeof(echo), cmd, args); + log(L_ERROR, "Cannot execute %s: %m", echo); + exit(255); +} + +int +run_command_v(byte *cmd, va_list args) +{ + pid_t p = fork(); + if (p < 0) + { + log(L_ERROR, "fork() failed: %m"); + return 0; + } + else if (!p) + exec_command_v(cmd, args); + else + { + int stat; + byte msg[EXIT_STATUS_MSG_SIZE]; + p = waitpid(p, &stat, 0); + if (p < 0) + die("waitpid() failed: %m"); + if (format_exit_status(msg, stat)) + { + byte echo[256]; + echo_command_v(echo, sizeof(echo), cmd, args); + log(L_ERROR, "`%s' failed: %s", echo, msg); + return 0; + } + return 1; + } +} + +void +echo_command_v(byte *buf, int size, byte *cmd, va_list args) +{ + byte *limit = buf + size - 4; + byte *p = buf; + byte *arg = cmd; + va_list cargs = args; + do + { + int l = strlen(arg); + if (p != buf && p < limit) + *p++ = ' '; + if (p+l > limit) + { + memcpy(p, arg, limit-p); + strcpy(limit, "..."); + return; + } + memcpy(p, arg, l); + p += l; + } + while (arg = va_arg(cargs, byte *)); + *p = 0; +} + +int +run_command(byte *cmd, ...) +{ + va_list args; + va_start(args, cmd); + int e = run_command_v(cmd, args); + va_end(args); + return e; +} + +void NONRET +exec_command(byte *cmd, ...) +{ + va_list args; + va_start(args, cmd); + exec_command_v(cmd, args); +} + +void +echo_command(byte *buf, int len, byte *cmd, ...) +{ + va_list args; + va_start(args, cmd); + echo_command_v(buf, len, cmd, args); + va_end(args); +} -- 2.39.2