]> mj.ucw.cz Git - libucw.git/commitdiff
Added a couple of functions for running of external commands with error
authorMartin Mares <mj@ucw.cz>
Sat, 10 Apr 2004 14:43:55 +0000 (14:43 +0000)
committerMartin Mares <mj@ucw.cz>
Sat, 10 Apr 2004 14:43:55 +0000 (14:43 +0000)
checking. A nice replacement for system().

lib/runcmd.c [new file with mode: 0644]

diff --git a/lib/runcmd.c b/lib/runcmd.c
new file mode 100644 (file)
index 0000000..df44f7d
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *     Sherlock Library -- Running of Commands
+ *
+ *     (c) 2004 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#include "lib/lib.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <alloca.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+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);
+}