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 63281a3..0d36186 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;