wlstony
wlstony

Reputation: 43

php file_put_contents no such file or directory occasionally

I start 8 processes to execute a job, the code in the job like this:

<?php
$dir = "/home/test/fileputcontents/0";
if(! is_dir($dir)){
    mkdir($dir, 0755, true);
}
file_put_contents("{$dir}/0.txt", "aaaa\n", FILE_APPEND | LOCK_EX);

but it raises an error which say "No such file or directory" sometimes,not very offen, thanks very much.

Is it because php_mkdir_ex method? Multi-process create directory at the same time.

/* DEPRECATED APIs: Use php_stream_mkdir() instead */
PHPAPI int php_mkdir_ex(const char *dir, zend_long mode, int options)
{
    int ret;

    if (php_check_open_basedir(dir)) {
        return -1;
    }

    if ((ret = VCWD_MKDIR(dir, (mode_t)mode)) < 0 && (options & REPORT_ERRORS)) {
        php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
    }

    return ret;
}

Upvotes: 2

Views: 890

Answers (3)

Jehong Ahn
Jehong Ahn

Reputation: 2386

Fixed in 8.1

https://github.com/php/php-src/pull/7383

- if (ret < 0) {
+ if (ret < 0 && errno != EEXIST) {

Upvotes: 0

wlstony
wlstony

Reputation: 43

Finally, I found the reason from php source code. It's because the directory creation collision. For example:

  1. We have 2 processes to create directory "/home/test/fileputcontents/0" at the same time.
  2. Now only /home directory exists, we need create test/fileputcontents/0
  3. One process (we call A) has created test, is going to create fileputcontents,anther process (we call B) is going to create test again, but it already exists.
  4. Then process B stopping creating directory, because it thinks all directories exist
  5. When B tries to call file_put_contents before A creates all the directories, then it warns "No such file or directory", because fileputcontents/0 does not exist.

My solution, create directories because processes start.

Upvotes: 2

Martin
Martin

Reputation: 101

Are all 8 processes running at the same time and writing to the same file? If two processes would write in the file at the same moment, it could be possible that the file is locked (caused by the LOCK_EX flag). So one process would win (can write to the file) and the other one would not wait, instead an error would be raised.

Upvotes: 0

Related Questions