Edit report at https://bugs.php.net/bug.php?id=60110&edit=1
ID: 60110
User updated by: tom at punkave dot com
Reported by: tom at punkave dot com
Summary: fclose(), file_put_contents(), copy() do not return
false properly
Status: Open
Type: Bug
Package: Filesystem function related
Operating System: all
PHP Version: 5.3.8
Block user comment: N
Private report: N
New Comment:
This can definitely happen with the regular stdio stuff. stdio employs
buffering
as a matter of course. It is a serious bug, not a change in behavior.
As for stream wrappers, the documentation specifies what stream_flush is
supposed to return, and fflush() would already be failing for people with bad
stream wrappers who did not heed that documentation.
stream_close is not supposed to return anything but is not affected by this bug
because stream_flush has already been called (and cheerfully ignored) before
stream_close is called (I checked).
So there is no need to change the behavior of stream_close (which would be a bc
break). We just need to pay attention to what stream_flush is already telling
us.
Previous Comments:
------------------------------------------------------------------------
[2011-10-21 21:23:22] [email protected]
See bug #53328. This is a good candidate for trunk, for stable versions I fear
(perhaps unfoundedly) that, because the return value of php_stream_close/free
is almost always ignored, some wrappers might have gotten away with incorrect
return values on the close handler.
------------------------------------------------------------------------
[2011-10-21 19:38:23] tom at punkave dot com
Description:
------------
The fclose() function does not check the result of flushing the stream:
if (!stream->is_persistent) {
zend_list_delete(stream->rsrc_id);
} else {
php_stream_pclose(stream);
}
RETURN_TRUE;
php_stream_pclose has a return value but it is ignored.
php_stream_pclose, in turn, calls _php_stream_free which flushes the stream but
does not check the return value either:
/* make sure everything is saved */
_php_stream_flush(stream, 1 TSRMLS_CC);
Contrary to the comment we did not make sure of anything (:
So the fix has to be made at least as deep as _php_stream_flush to be
effective.
I have verified that _php_stream_flush does pay attention to the result of the
underlying flush operation. Note that fflush() reports write errors
successfully
while fclose() doesn't).
In many environments, including stdio (plain old files), the final write to
disk
might not sometimes occur until the stream is flushed by _php_stream_flush. If
this fails, for instance because the disk is full, PHP pays no heed to the
error.
This is especially obvious if you use a stream wrapper that does its actual
writing when the stream is closed (for instance storing an object with a single
HTTP request), but again, it could happen with normal files too.
Because of this deeper issue with _php_stream_free, all other PHP convenience
functions for files such as copy() and file_put_contents() also fail to
correctly report false when the final flush of data to disk fails when closing
a
file.
This has serious consequences for any application that is counting on data
integrity, which would be pretty much every application that uses files I guess.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=60110&edit=1