chiark / gitweb /
Use new mdup(3mLib) function.
[tripe] / client / tripectl.c
index e2411afb304cf6b8776c2fbd0c96ef9f865dab20..514506162429860fd6047c85db2b49159c08b2ca 100644 (file)
@@ -52,6 +52,7 @@
 #include <mLib/daemonize.h>
 #include <mLib/darray.h>
 #include <mLib/dstr.h>
+#include <mLib/mdup.h>
 #include <mLib/mdwopt.h>
 #include <mLib/quis.h>
 #include <mLib/report.h>
@@ -120,6 +121,30 @@ static void checkbg(char **p)
     die(EXIT_FAILURE, "unexpected background tag `%s'", q);
 }
 
+static void dolog(int prio, const char *msg, ...)
+{
+  va_list ap;
+  dstr d = DSTR_INIT;
+  const char *cat;
+
+  va_start(ap, msg);
+  dstr_vputf(&d, msg, &ap);
+  va_end(ap);
+  if (f & f_syslog) syslog(prio, "%s", d.buf);
+  if (logfp) {
+    switch (prio) {
+      case LOG_WARNING: cat = "warning"; break;
+      case LOG_DEBUG: cat = "debug"; break;
+      case LOG_ERR: cat = "error"; break;
+      default: cat = "message"; break;
+    }
+    writelog(cat, d.buf);
+  }
+  if (prio == LOG_WARNING && (f & f_warn))
+    fprintf(stderr, "Warning: %s\n", d.buf);
+  dstr_destroy(&d);
+}
+
 static void checkfg(void)
   { if (bgtag) die(EXIT_FAILURE, "unexpected foreground response"); }
 
@@ -134,28 +159,13 @@ static void cline(char *p, size_t len, void *b)
   q = str_getword(&p);
   if (!q)
     return;
-  if (strcmp(q, "WARN") == 0) {
-    if (f & f_syslog)
-      syslog(LOG_WARNING, "%s", p);
-    if (logfp)
-      writelog("warning", p);
-    if (f & f_warn)
-      fprintf(stderr, "Warning: %s\n", p);
-  } else if (strcmp(q, "TRACE") == 0) {
-    if (f & f_syslog)
-      syslog(LOG_DEBUG, "%s", p);
-    if (logfp)
-      writelog("debug", p);
-  } else if (!(f & f_command)) {
-    if (f & f_syslog)
-      syslog(LOG_ERR, "unexpected output `%s %s'", q, p);
-    if (logfp) {
-      dstr d = DSTR_INIT;
-      dstr_putf(&d, "unexpected output `%s %s'", q, p);
-      writelog("error", d.buf);
-      dstr_destroy(&d);
-    }
-  } else if (strcmp(q, "FAIL") == 0) {
+  if (strcmp(q, "WARN") == 0)
+    dolog(LOG_WARNING, p);
+  else if (strcmp(q, "TRACE") == 0)
+    dolog(LOG_DEBUG, p);
+  else if (!(f & f_command))
+    dolog(LOG_ERR, "unexpected output `%s %s'", q, p);
+  else if (strcmp(q, "FAIL") == 0) {
     checkfg();
     die(EXIT_FAILURE, "%s", p);
   } else if (strcmp(q, "INFO") == 0) {
@@ -208,6 +218,16 @@ static void uline(char *p, size_t len, void *b)
   }
 }
 
+static void eline(char *p, size_t len, void *b)
+{
+  if (p)
+    dolog(LOG_WARNING, "(stderr): %s", p);
+  else {
+    selbuf_destroy(b);
+    close(fd);
+  }
+}
+
 static void setup(const char *cmd)
 {
   dstr d = DSTR_INIT;
@@ -264,7 +284,7 @@ static void logfile(const char *name)
     else if (logname)
       die(EXIT_FAILURE, d.buf);
     if (f & f_syslog)
-      syslog(LOG_ERR, d.buf);
+      syslog(LOG_ERR, "%s", d.buf);
     dstr_destroy(&d);
   }
 }
@@ -347,12 +367,13 @@ int main(int argc, char *argv[])
   size_t sz;
   uid_t u = -1;
   gid_t g = -1;
-  int pfd[2];
+  int pfd[2], efd[2];
+  mdup_fd md[3];
   pid_t kid;
   struct sigaction sa;
   sigset_t newmask, oldmask;
   struct sockaddr_un sun;
-  selbuf bu, bs;
+  selbuf bu, bs, be;
   dstr d = DSTR_INIT;
   sig hup;
 
@@ -489,7 +510,7 @@ int main(int argc, char *argv[])
     putarg(&spawnopts, "-d.");
     putarg(&spawnopts, "-F");
     putarg(&spawnopts, "%s", spawnpath);
-    if (socketpair(PF_UNIX, SOCK_STREAM, 0, pfd))
+    if (socketpair(PF_UNIX, SOCK_STREAM, 0, pfd) || pipe(efd))
       die(EXIT_FAILURE, "error from socketpair: %s", strerror(errno));
     sigemptyset(&newmask);
     sigaddset(&newmask, SIGCHLD);
@@ -497,10 +518,11 @@ int main(int argc, char *argv[])
     if ((kid = fork()) < 0)
       die(EXIT_FAILURE, "fork failed: %s", strerror(errno));
     if (!kid) {
-      dup2(pfd[1], STDIN_FILENO);
-      dup2(pfd[1], STDOUT_FILENO);
-      close(pfd[0]);
-      close(pfd[1]);
+      close(pfd[0]); close(efd[0]);
+      md[0].cur = pfd[1]; md[0].want = STDIN_FILENO;
+      md[1].cur = pfd[1]; md[1].want = STDOUT_FILENO;
+      md[2].cur = efd[1]; md[2].want = STDERR_FILENO;
+      mdup(md, 3);
       if (logfp) fclose(logfp);
       if (pidfp) fclose(pidfp);
       closelog();
@@ -510,7 +532,8 @@ int main(int argc, char *argv[])
     }
     sigprocmask(SIG_SETMASK, &oldmask, 0);
     fd = pfd[0];
-    close(pfd[1]);
+    close(pfd[1]); close(efd[1]);
+    selbuf_init(&be, &sel, efd[0], eline, &be);
   } else {
     sz = strlen(sock) + 1;
     if (sz > sizeof(sun.sun_path))