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;

Reply via email to