#22488 [Opn->Bgs]: Permission denied for unlink() , copy(), rename(), move_uploaded_file() FAT32

114 views
Skip to first unread message

w...@php.net

unread,
Mar 2, 2003, 6:18:37 AM3/2/03
to
ID: 22488
Updated by: w...@php.net
Reported By: kemal at thelimelight dot nl
-Status: Open
+Status: Bogus
Bug Type: Filesystem function related
Operating System: Windows NT 4.0 SP6
PHP Version: 4.2.3
New Comment:

Not a bug in PHP; PHP cannot write to a file that is in use; it is your
responsibility to work around this problem with IIS in your script.

As a suggestion, you could try adding a 2 second sleep before
attempting to move the file; this should allow enough time for the OS
to decide that the access is OK.

Previous Comments:
------------------------------------------------------------------------

[2003-03-02 03:49:28] kemal at thelimelight dot nl

**** New Discovery: the 'permission denied' problem outlined above only
manifests itself when the existing file to be overwriten has just been
recently accessed by IIS (ie the image file has been very recently
requested by a HTML page).

Eliminating the line which contains the <IMG SRC="%s"> tag in the
sample script above results in perfect running of the script.

Conclusion: any attempt to overwrite the file was denied by the OS (NT4
in my case) because the file was marked "in-use". It should not have
been so, because the file is only accessed for a short time, and it
happened a few minutes before. I don't know whether this is an IIS bug
or PHP bug.

------------------------------------------------------------------------

[2003-03-01 20:06:07] kemal at thelimelight dot nl

**** Additional test done with PHP 4.3.2-dev (build date Mar 2 2003
02:16:38): same result as with previous versions.

------------------------------------------------------------------------

[2003-03-01 11:36:26] w...@php.net

Please try using this CVS snapshot:

http://snaps.php.net/php4-STABLE-latest.tar.gz

For Windows:

http://snaps.php.net/win32/php4-win32-STABLE-latest.zip

------------------------------------------------------------------------

[2003-03-01 10:18:27] kemal at thelimelight dot nl

(I have tested this with PHP 4.2.3 and PHP 4.3.1 running as a CGI
process under IIS 4 on NT4-SP6 server with FAT file system)

The situation:
After receiving a submission from an HTML form which includes an
uploaded file, I need to move the uploaded file from its temporary
place to its final place.

The problem:
Whenever the target location already have a file with the same name,
the PHP command would fail with either 'unable to create' and/or
'permission denied' type of warnings. It does not matter whether I use
one simple move_uploaded_file() function or a combination of unlink(),
copy() and rename() functions. It even fails when I use the system()
or exec() function. Please remember that the existing file is not
marked 'read-only' and the user account (I_USR) does have write
capability on the intended directory.

I have already tried using double backward slash as path separator
(instead of forward slash), using full path to root of drive (instead
of relative), giving I_USR account administrator priviledges, sharing
the target directory, moving temp directory to the same drive as the
target directory, disabling warning message generation (using the @
prefix), trying to unlink or move the files using multiple strategy one
after the other, etc.

Interesting behaviour:
The PHP commands would not always fail. Once in a while, it would
succeed. Espescially after the script has died. (Seems to react
differently when there is a time lapse)

**** SAMPLE SCRIPT FOR BUG TESTING:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
<title>upload test</title>
<META HTTP-EQUIV="PRAGMA" CONTENT="no-cache">
<META HTTP-EQUIV="expires" CONTENT="Fri, 1 January 1999 12:00:00 EST">

</head>

<body>
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="65536">
<?php

$vname = 'myfile';

$target = './my_uploaded_image.jpg';

$name = $_FILES[$vname]['name'];
$type = $_FILES[$vname]['type'];
$size = $_FILES[$vname]['size'];
$temp = $_FILES[$vname]['tmp_name'];
$err = $_FILES[$vname]['error'];

if (is_uploaded_file($temp)) {
if (!move_uploaded_file($temp, $target)) {
echo "<strong>Error:</strong> Unable to accept file $name<br>";
}
}

if (is_file($target)) {
echo sprintf('<img src="%s" border="0">', $target);
} else {
echo "(no image file)";
}

?><br>
Specify here an jpeg image file to be uploaded:<br>
<input type="file" name="<?php echo $vname; ?>"><br>
<input type="Submit" value="Upload">
</form>


</body>
</html>

**** WORK AROUND THAT SEEMS TO WORK:
change the simple move_uploaded_file() invocation to:

$n = 0;
while (!@move_uploaded_file($temp, $target) and $n<100) {
clearstatcache();
sleep(1);
$n++;
}

------------------------------------------------------------------------


--
Edit this bug report at http://bugs.php.net/?id=22488&edit=1

Reply all
Reply to author
Forward
0 new messages