Thursday, December 7, 2017

'unlink', Permission denied error when executing function [exec]

Leave a Comment

This is the file test1.php:

 <?php         set_time_limit(0);     for($i= 1;$i<5000 ;$i++){          $comm_sjis = "echo 'test'";         $result = exec($comm_sjis);      }     unset($result);     echo 'ok'; 

This is file test2.php:

<?php  set_time_limit(0);  function write_txt($str) {     $filepath = 'E:/temp/test.xml';     if (($fp = @fopen($filepath, "a")) === false) {         return;     }      if (!flock($fp, LOCK_EX)) {         @fclose($fp);         return;     }      if (fwrite($fp, $str . "\n") === false) {         @flock($fp, LOCK_UN);         @fclose($fp);         return;     }      if (!fflush($fp)) {         @flock($fp, LOCK_UN);         @fclose($fp);         return;     }      if (!flock($fp, LOCK_UN)) {         @fclose($fp);         return;     }      if (!fclose($fp)) {         return;     } }  for($i= 1;$i<100 ;$i++){      write_txt('test');       unlink('E:/temp/test.xml'); } echo 'ok'; 

If I run file test2.php while test1.php is running, an error will occur:

Warning: unlink(E:/temp/test.xml): Permission denied in C:\xampp\htdocs\test2.php on line 45

When I only run test2.php, without test1.php, this error does not occur. Why does unlink give a Permission denied error when I execute the function?

I'm using XAMPP with Windows 7.

3 Answers

Answers 1

You're silencing errors in fopen which means that if, at any point, the file fails to open (perhaps because of a memory limit being reached in XAMPP, for example), you'd have no way of knowing in your script (you can view it in your logs).

From the PHP Manual:

bool unlink ( string $filename [, resource $context ] )

Deletes filename. Similar to the Unix C unlink() function. An E_WARNING level error will be generated on failure.

unlink deletes a file. That means that if your file fails to open using fopen, and you haven't created it already, it may well not exist. Trying to unlink a file that does not exist will result in an error.

An easy solution would be to silence errors on unlink as well.

@unlink('E:/temp/test.xml'); 

That way it will fail gracefully if your function fails to write a file. Another option is to check if the file exists before trying to unlink.

$file = 'E:/temp/test.xml'; if (file_exists($file)) {     error_log(‘could not write file’);     unlink($file); } 

My favored option in this case might be to use Exceptions. When you fail to open or fail to unlock a file, throw an Exception. You can catch it, log the issue and break the loop before you try to unlink.

That should help you debug what is going on.

A couple final notes: I run Linux, so it’s not easy for me to test this behavior on a Windows 7 XAMPP machine. However, I suspect it is because the system is locking due to limited I/O resources. flock in a massive loop and echo in a massive loop means that resources can fail. If you intend to run something like this in production you won’t run into it as often but you will still need to account for it.

Consider your code carefully. I have to stress this, unlink returns this error even if the file doesn’t exist. Assuming unlink is the problem is not a safe assumption at all.

As stated, silencing unlink or checking to see if the file exists will silence this error.

Answers 2

Permission is denied, because the file is being used by another process.
Try fclose on file, before running to unlink.

Answers 3

Try this

 unlink ('E://temp//test.xml'); 

You might notice that you original code uses // to create but only / to delete.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment