Re: cvs: php4 /ext/standard file.c
| From: | Michael Widenius | Date: | Sat, 23 Dec 2000 19:42:21 +0000 |
| Subject: | Re: cvs: php4 /ext/standard file.c | ||
| References: | 1 2 3 | Groups: | php.cvs |
| Request: | Send a blank email to php-cvs+get-3284@lists.php.net to get a copy of this message | ||
Hi!
>>>>> "Zeev" == Zeev Suraski <zeev@zend.com> writes:
Zeev> At 14:43 23/12/2000, Michael Widenius wrote:
>> >> This code is a good example of the write() API problem. If
>> >> write() does not return Count, the code assumes that errno
>> >> was set by write(). If errno was not set by write(), the
>> >> code will simply take the error code from a previous system
>> >> call and reinterprete it in this context. That is pretty
>> >> much wrong, considering the following three paragraphs:
>> >>
>>
>> The above is not really right; If you check the code of my_write(),
>> it only uses errno if write() returns 0 or -1, in which case
>> errno should contain the right error code.
Zeev> I can't see how it does that... What if Count equals 1024, but write()
Zeev> returns only 512? It won't reach the 'break' statement, and will fall
Zeev> through and use errno.
If it falls through, it will just schedule another write without using
errno (except in the case where write() returned 0 or -1, in which
case it's ok to check errno)
Zeev> Sascha's main concern is this:
Zeev> (a) according to the documentation, errno is only set if write() returns -1
Zeev> - a 'complete' error code.
In most systems it's set if write() returns -1 or 0; Note that
according to the specification write() should never return 0 except if
Count is 0, but in practice this happens!
Zeev> (b) when reaching the end of the disk space, we may have a situation where
Zeev> a write() will succeed partially, i.e., it will write bytes, but not as
Zeev> many as we asked. In this case, write() will return a positive integer,
Zeev> that is lower than the count we sent it.
No, it will not; If write() returns a lower number my_write() will
return with another write() until this returns 0 or -1
Zeev> The big question is - whether
Zeev> errno will be set or not. The documentation says nothing about it. It's
Zeev> extremely odd if it won't be set though, because it would then essentially
Zeev> mean that there's no way to properly handle this situation.
It will not be set :( (I agree that this is a stupid specification) On
the other hand, my_write() handles this case without any problems!
To satisfy Sascha, I changed the test of ENOSCP to:
if (my_errno == ENOSPC && (MyFlags & MY_WAIT_IF_FULL) &&
(uint) writenbytes != (uint) -1)
this will take care of a theoretical bug when errno contained ENOSPC
from an old call. Just note that the old code worked, even if it was
not optimal in this case.
Zeev> Question is - do you have real world experience with this?
I know that my_write() has worked perfectly for us during the last 10
years, with and without threads...
Regards,
Monty