Le 22/11/2013 11:09, Stuart Henderson a écrit :
> 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;
> 

Yes but, if the write() always fails, there's an infinite loop here.

Reply via email to