---------------------------------------------------------------- Date sent: Mon, 9 Feb 1998 08:03:12 +0100 (CET) From: Andreas Jaeger To: inn-bugs@isc.org Subject: Endless loop in batcher.c In inn 1.7.1 you might get an endless loop without the following patch. For an explanation see my comment below. There are other places that do go in a loop when EINTR occurs but don't reset this. I think that the whole of INN should be checked for this. Andreas P.S. Here's an output of strace for that loop: read(4, "Path: arthur.rhein-neckar.de!not"..., 8192) = 1602 write(1, "Path: arthur.rhein-neckar.de!not"..., 1602) = 1602 read(4, "", 8192) = 0 read(4, "", 8192) = 0 read(4, "", 8192) = 0 [----defective patch deleted---] -- Andreas Jaeger aj@arthur.rhein-neckar.de jaeger@informatik.uni-kl.de for pgp-key finger ajaeger@alma.student.uni-kl.de ---------------------------------------------------------------- From: Don Lewis Date sent: Mon, 9 Feb 1998 01:15:49 -0800 To: Andreas Jaeger , inn-bugs@isc.org Subject: Re: Endless loop in batcher.c On Feb 9, 8:03am, Andreas Jaeger wrote: } Subject: Endless loop in batcher.c } } In inn 1.7.1 you might get an endless loop without the following } patch. For an explanation see my comment below. There are other } places that do go in a loop when EINTR occurs but don't reset this. I } think that the whole of INN should be checked for this. Your patch really isn't quite right either. Errno should only be examined when read() returns -1. Also, even if you reset errno where you do, fwrite() can still muck with it. The code should be something more like: while ((i = read(artfd, (POINTER)data, datasize)) != 0) { if (i > 0) { if (fwrite((POINTER)data, (SIZE_T)1, (SIZE_T)i, F) != i) break; } else if (errno != EINTR) break; } --- Truck ---------------------------------------------------------------- Patch below inserted by Forrest J. Cavalier, III, Mib Software --- backends/batcher.c.orig Tue Dec 17 05:40:40 1996 +++ backends/batcher.c Mon Mar 02 11:32:02 1998 @@ -468,9 +468,14 @@ /* Write the article. In case of interrupts, retry the read but * not the fwrite because we can't check that reliably and * portably. */ - while ((i = read(artfd, (POINTER)data, datasize)) > 0 || errno == EINTR) - if (fwrite((POINTER)data, (SIZE_T)1, (SIZE_T)i, F) != i) - break; + while ((i = read(artfd, (POINTER)data, datasize)) != 0) { + if (i > 0) { + if (fwrite((POINTER)data, (SIZE_T)1, (SIZE_T)i, F) != i) + break; + } else if (errno != EINTR) + break; + } + if (ferror(F)) { (void)fprintf(stderr, "batcher %s cant write article %s\n", Host, strerror(errno));