From: Mark Wooding Date: Thu, 27 Apr 2006 19:33:39 +0000 (+0100) Subject: addrcheck: Run address verification services with a timeout. X-Git-Tag: 1.03-6~2 X-Git-Url: https://git.distorted.org.uk/~mdw/qmail/commitdiff_plain/e7392cec2d435b867af537c0a46ef77ba600abb8 addrcheck: Run address verification services with a timeout. 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. --- diff --git a/addrcheck.c b/addrcheck.c index 63281a3..0d36186 100644 --- a/addrcheck.c +++ b/addrcheck.c @@ -7,7 +7,9 @@ #include #include -/* #define DEBUG */ +#if defined(TEST) && !defined(DEBUG) +# define DEBUG +#endif #ifdef DEBUG # define D(x) x # include @@ -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;