chiark / gitweb /
addrcheck: Run address verification services with a timeout.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 27 Apr 2006 19:33:39 +0000 (20:33 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 27 Apr 2006 19:33:39 +0000 (20:33 +0100)
This entails reordering the code which reads the answer, to check for
the process exiting before reading its output.  This also means that
we deadlock the service if it tries to write more than a pipe-buffer's
worth of stuff, but we're expecting a single character, dammit -- it
shouldn't try to give us an essay.

If the timeout goes off, we report a temporary failure, as with any
other untoward situation.

addrcheck.c

index 63281a32f45559ec19350add0f5454c48dacf68f..0d36186c50bc1ef53140bd17068fbf926ab9d13f 100644 (file)
@@ -7,7 +7,9 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-/* #define DEBUG */
+#if defined(TEST) && !defined(DEBUG)
+#  define DEBUG
+#endif
 #ifdef DEBUG
 #  define D(x) x
 #  include <stdio.h>
@@ -134,21 +136,24 @@ static int localprobe(int cdb, const char *sender,
     if (!kid) {
       close(0); open("/dev/null", O_RDONLY);
       dup2(p[1], 1);
+#ifndef DEBUG
       close(2); open("/dev/null", O_WRONLY);
+#endif
       close(p[0]); close(p[1]);
       execl("/usr/bin/userv", "/usr/bin/userv",
-           "-f", "stdin=/dev/null",
+           "-f", "stdin=/dev/null", "-t", "10",
            u.s, serv.s,
            tail, sender, key, k + 1,
            (char *)0);
       _exit(127);
     }
     close(p[1]);
+    if (wait_pid(&wstat, kid) < 0) { close(p[0]); return (-1); }
+    D( fprintf(stderr, "userv exited with status %d\n", wstat); )
+    if (wstat) { close (p[0]); errno = EAGAIN; return (-1); }
     n = read(p[0], &ch, 1);
+    if (n != 1) { close (p[0]); errno = EAGAIN; return (-1); }
     close(p[0]);
-    if (wait_pid(&wstat, kid) < 0) { return (-1); }
-    D( fprintf(stderr, "userv exited with status %d\n", wstat); )
-    if (n != 1 || wstat) { errno = EAGAIN; return (-1); }
     D( fprintf(stderr, "userv answer was `%c'\n", ch); )
   } else if (dlen != 1) {
     errno = EIO;