On 2013/11/22 07:25, Maxime Villard wrote:
> Hi,
> a thing I spotted some weeks ago
>
> - - - usr.bin/ftp/ftp.c l.1090 - - -
>
> d = 0;
> do {
> wr = write(fileno(fout), buf + d, rd);
> if (wr == -1 && errno == EPIPE)
> break;
> d += wr;
> rd -= wr;
> } while (d < c);
>
> If write() fails without EPIPE, d is decremented, and the function
> keeps looping. If write() succeeds after several loops, d will be
> negative, and the function will write from buf-XX.
>
> Since d is later used to display a proper error message, I'd suggest
> this patch:
>
>
> Index: ftp.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/ftp/ftp.c,v
> retrieving revision 1.83
> diff -u -r1.83 ftp.c
> --- ftp.c 13 Nov 2013 20:41:14 -0000 1.83
> +++ ftp.c 22 Nov 2013 06:23:32 -0000
> @@ -1094,7 +1094,7 @@
> break;
> d += wr;
> rd -= wr;
> - } while (d < c);
> + } while (d < c && d > 0);
> if (rd != 0)
> break;
> bytes += c;
>
>
> Any opinion?
>
Shouldn't it be something more like this? Otherwise if the write() fails,
we attempt writing one byte fewer for every retry.
Index: ftp.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp.c,v
retrieving revision 1.83
diff -u -p -r1.83 ftp.c
--- ftp.c 13 Nov 2013 20:41:14 -0000 1.83
+++ ftp.c 22 Nov 2013 10:08:16 -0000
@@ -1090,10 +1090,13 @@ recvrequest(const char *cmd, const char
d = 0;
do {
wr = write(fileno(fout), buf + d, rd);
- if (wr == -1 && errno == EPIPE)
- break;
- d += wr;
- rd -= wr;
+ if (wr == -1) {
+ if (errno == EPIPE)
+ break;
+ } else {
+ d += wr;
+ rd -= wr;
+ }
} while (d < c);
if (rd != 0)
break;