Hi Ingo,

Thanks very much for your time and detailed explanation!

I have one more question:

If write(2) indeed returns 0, the write(2) won't set errno variable,
ring? Because from the manual, the errno is set only when the return
value is -1. If this is true, the errno's value should be set by last
system call which failed, and has no relation with current write(2). So
it is not guaranteed that following words will be print:

program: write: Undefined error: 0

It may print a totally unrelated description which can mislead the user.


Does my concern make sense? Please correct me if I am wrong, thanks very
much in advance!

On 9/26/2018 10:33 PM, Ingo Schwarze wrote:
> Hi,
> 
> Nan Xiao wrote on Wed, Sep 26, 2018 at 09:42:02PM +0800:
> 
>> Any developer can comment on this patch? Thanks!
> 
> I think this change is a bad idea and should not be committed.
> 
> No matter whether or not it can happen on OpenBSD, *if* some
> implementation of write(2) sometimes returns 0 even for nbytes > 0,
> your change is likely to cause an infinite busy loop, which is
> quite bad.
> 
> In that case, the current code would print:
> 
>   program: write: Undefined error: 0
> 
> That's admittedly not totally informative, but we can't do much
> better because it is indeed not quite clear which kind of problem
> the return value of 0 might indicate.  And in any case, that edge
> case seems uncommon enough that complicating the example code to
> handle the case of a return value of zero separately would also
> seem like a bad idea.
> 
> Besides, the idiom documented here is actually widely used in the
> tree, and it is indeed recommended, see for example
> 
>   /usr/src/bin/cat/cat.c
> 
> Yours,
>   Ingo
> 
> 
>> I am reading write(2) manual, and come across the following example:
>>
>> for (off = 0; off < bsz; off += nw)
>>      if ((nw = write(d, buf + off, bsz - off)) == 0 || nw == -1)
>>              err(1, "write");
>>
>> I am just wondering when the write(2) will return 0? If in some cases,
>> it will indeed return 0, according to the manual:
>>
>> Upon successful completion the number of bytes which were written is
>> returned. Otherwise, a -1 is returned and the global variable errno is
>> set to indicate the error.
>>
>> Because the errno is only set when return value is -1, if write(2)
>> returns 0, the errno should be an undefined value, and "err(1,
>> "write");" also won't print correct information.
>>
>> If write(2) won't return 0, my following patch fixes the example code:
>>
>> diff --git write.2 write.2
>> index c1686b1a910..db134959002 100644
>> --- write.2
>> +++ write.2
>> @@ -164,7 +164,7 @@ ssize_t nw;
>>  int d;
>>
>>  for (off = 0; off < bsz; off += nw)
>> -    if ((nw = write(d, buf + off, bsz - off)) == 0 || nw == -1)
>> +    if ((nw = write(d, buf + off, bsz - off)) == -1)
>>              err(1, "write");
>>  .Ed
>>  .Sh ERRORS

-- 
Best Regards
Nan Xiao(肖楠)

Reply via email to