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.