chiark / gitweb /
Reopen logfiles on receipt of @SIGHUP@ (not done very well). Don't
[tripe] / client.c
index e78f86e7829fae3e5593c34b38d1b750746506a5..ce1acb6520ab9f294c23ab571119e88f5dded4e6 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: client.c,v 1.2 2001/02/04 01:17:54 mdw Exp $
+ * $Id: client.c,v 1.3 2001/02/04 17:10:15 mdw Exp $
  *
  * Client for TrIPE
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: client.c,v $
+ * Revision 1.3  2001/02/04 17:10:15  mdw
+ * Reopen logfiles on receipt of @SIGHUP@ (not done very well).  Don't
+ * change directory -- just mangle pathnames instead.
+ *
  * Revision 1.2  2001/02/04 01:17:54  mdw
  * Create a configuration header file to tidy up command lines.
  *
@@ -88,6 +92,7 @@
 static FILE *logfp = 0;
 static unsigned f = 0;
 static int fd;
+static volatile sig_atomic_t reopen = 0;
 
 #define f_bogus 1u
 #define f_spawn 2u
@@ -110,6 +115,11 @@ static void reap(int sig)
   errno = e;
 }
 
+static void sighup(int sig)
+{
+  reopen = 1;
+}
+
 static void writelog(const char *cat, const char *msg)
 {
   char buf[256];
@@ -185,6 +195,17 @@ static void uline(char *p, void *b)
   }
 }
 
+static void logfile(const char *name)
+{
+  if (logfp)
+    fclose(logfp);
+  if ((logfp = fopen(name, "a")) == 0) {
+    die(EXIT_FAILURE, "error opening logfile `%s': %s",
+       name, strerror(errno));
+  }
+  setvbuf(logfp, 0, _IOLBF, BUFSIZ);
+}
+
 static void version(FILE *fp)
 {
   pquis(fp, "$, TrIPE version " VERSION "\n");
@@ -234,6 +255,7 @@ int main(int argc, char *argv[])
   const char *sock = "tripesock";
   const char *spawnpath = "tripe";
   string_v spawnopts = DA_INIT;
+  const char *logname = 0;
   char *p;
 
   ego(argv[0]);
@@ -301,12 +323,8 @@ int main(int argc, char *argv[])
        f |= f_warn;
        break;
       case 'f':
-       if (logfp)
-         fclose(logfp);
-       if ((logfp = fopen(optarg, "a")) == 0) {
-         die(EXIT_FAILURE, "error opening logfile `%s': %s",
-             optarg, strerror(errno));
-       }
+       logname = optarg;
+       logfile(logname);
        f |= f_noinput;
        break;
       default:
@@ -319,13 +337,6 @@ int main(int argc, char *argv[])
     exit(EXIT_FAILURE);
   }
 
-  /* --- Set the world up --- */
-
-  if (chdir(dir)) {
-    die(EXIT_FAILURE, "couldn't set current directory to `%s': %s",
-       dir, strerror(errno));
-  }
-
   /* --- Connect to the server --- */
 
   if (f & f_spawn) {
@@ -344,7 +355,8 @@ int main(int argc, char *argv[])
 
     DA_UNSHIFT(&spawnopts, (char *)spawnpath);
     if (!(f & f_spawnopts)) {
-      DA_PUSH(&spawnopts, "-d.");
+      DA_PUSH(&spawnopts, "-d");
+      DA_PUSH(&spawnopts, (char *)dir);
       DA_PUSH(&spawnopts, "-a");
       DA_PUSH(&spawnopts, (char *)sock);
     }
@@ -361,6 +373,9 @@ int main(int argc, char *argv[])
       dup2(pfd[1], STDOUT_FILENO);
       close(pfd[1]);
       close(pfd[0]);
+      if (logfp)
+       fclose(logfp);
+      closelog();
       execvp(DA(&spawnopts)[0], DA(&spawnopts));
       die(127, "couldn't exec `%s': %s", spawnpath, strerror(errno));
     }
@@ -370,17 +385,20 @@ int main(int argc, char *argv[])
   } else {
     struct sockaddr_un sun;
     size_t sz = strlen(sock) + 1;
-    if (sz > sizeof(sun.sun_path))
+    dstr d = DSTR_INIT;
+    dstr_putf(&d, "%s/%s", dir, sock);
+    if (d.sz + 1 > sizeof(sun.sun_path))
       die(EXIT_FAILURE, "socket name `%s' too long", sock);
     memset(&sun, 0, sizeof(sun));
     sun.sun_family = AF_UNIX;
-    memcpy(sun.sun_path, sock, sz);
-    sz += offsetof(struct sockaddr_un, sun_path);
+    memcpy(sun.sun_path, d.buf, d.sz + 1);
+    sz = d.sz + offsetof(struct sockaddr_un, sun_path) + 1;
+    dstr_destroy(&d);
     if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
       die(EXIT_FAILURE, "error making socket: %s", strerror(errno));
     if (connect(fd, (struct sockaddr *)&sun, sz)) {
       die(EXIT_FAILURE, "error connecting to `%s': %s",
-         sock, strerror(errno));
+         sun.sun_path, strerror(errno));
     }
   }
 
@@ -427,11 +445,27 @@ int main(int argc, char *argv[])
     lbuf_init(&b, cline, 0);
     if (f & f_syslog)
       openlog(QUIS, 0, LOG_DAEMON);
+    if (logfp) {
+      struct sigaction sa;
+      sa.sa_handler = sighup;
+      sa.sa_flags = 0;
+      sigemptyset(&sa.sa_mask);
+      sigaction(SIGHUP, &sa, 0);
+    }
     for (;;) {
-      size_t sz = lbuf_free(&b, &p);
-      ssize_t n = read(fd, p, sz);
-      if (n < 0)
+      size_t sz;
+      ssize_t n;
+      if (reopen) {
+       logfile(logname);
+       reopen = 0;
+      }
+      sz = lbuf_free(&b, &p);
+      n = read(fd, p, sz);
+      if (n < 0) {
+       if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
+         continue;
        die(EXIT_FAILURE, "read failed: %s", strerror(errno));
+      }
       if (n == 0)
        break;
       lbuf_flush(&b, p, n);