Bug #15327 Updated: copy() causes bus error with files which change size
| From: | sniper@php.net | Date: | Tue, 18 Jun 2002 00:14:40 +0000 |
| Subject: | Bug #15327 Updated: copy() causes bus error with files which change size | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-10978@lists.php.net to get a copy of this message | ||
ID: 15327
Updated by: sniper@php.net
Reported By: derrell@vis-av.com
-Status: Open
+Status: Feedback
Bug Type: Reproducible crash
Operating System: Linux 2.4.7-10, Redhat 7.2
PHP Version: 4.1.1
New Comment:
Can you please try this snapshot:
http://snaps.php.net/php4-latest.tar.gz
Previous Comments:
------------------------------------------------------------------------
[2002-02-01 13:37:45] derrell@vis-av.com
The copy() function (actually php_copy_file() at
ext/standard/file.c:1934) uses mmap() when available. The mmap()
function has the documented "feature" (bug!) that if the file that is
mapped is truncated (e.g. by another process) after mmap() is called, a
SIGBUS (bus error) signal is generated during the write() to the
destination file using the mmap'ed pointer as the source of the write.
This, of course, crashes php.
I can not find a workaround for this. I have not been able to find any
combination of flags to pass to mmap such that mmap() will fail
gracefully rather than write() failing non-gracefully. Don't use
mmep()? That would be a shame, but seems to be the solution.
Simple example. Note that /computers/win95 is an smbmount'ed file
system. The file being accessed here, a Window's swap file, is of
course changing all the time.
<?php
copy("/computers/win95/C/WINDOWS/WIN386.SWP", "/tmp/zzz");
?>
Here's a simple C program which replicates what's going on in
php_copy_file()
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main(int argc, char * argv[])
{
int fdSrc;
int fdDest;
int len;
char buf[8192];
void * srcfile;
struct stat sbuf;
if ((fdSrc = open("/computers/win95/C/WINDOWS/WIN386.SWP", 0)) < 0)
{
perror("open");
exit(1);
}
if ((fdDest = creat("/tmp/zzz", 0777)) < 0)
{
perror("creat");
exit(1);
}
if (fstat(fdSrc, &sbuf))
{
perror("fstat");
exit(1);
}
srcfile = mmap(NULL, sbuf.st_size, PROT_READ, MAP_SHARED, fdSrc, 0);
printf("srcfile=%p\n", srcfile);
if (srcfile != (void *) MAP_FAILED)
{
if ((len = write(fdDest, srcfile, sbuf.st_size)) !=
sbuf.st_size)
{
printf("write returned %d; expected %d\n", len,
sbuf.st_size);
}
munmap(srcfile, sbuf.st_size);
}
printf("Success\n");
close(fdSrc);
close(fdDest);
exit(0);
}
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=15327&edit=1