public static function open($path, $flags, $cb, $mode = null, $pri = EIO_PRI_DEFAULT) { if (self::$supported) { $fdCacheKey = $path . "" . $flags; $noncache = strpos($flags, '!') !== false; $flags = File::convertFlags($flags); if (!$noncache && ($item = FS::$fdCache->get($fdCacheKey))) { // cache hit $file = $item->getValue(); if ($file === null) { // operation in progress $item->addListener($cb); } else { // hit call_user_func($cb, $file); } return; } elseif (!$noncache) { $item = FS::$fdCache->put($fdCacheKey, null); $item->addListener($cb); } return eio_open($path, $flags, $mode, $pri, function ($arg, $fd) use($cb, $path, $flags, $fdCacheKey, $noncache) { if (!$fd) { if ($noncache) { call_user_func($cb, false); } else { FS::$fdCache->put($fdCacheKey, false, self::$badFDttl); } return; } $file = new File($fd); $file->append = ($flags | EIO_O_APPEND) === $flags; $file->path = $path; if ($file->append) { $file->stat(function ($file, $stat) use($cb, $noncache, $fdCacheKey) { $file->pos = $stat['size']; if (!$noncache) { $file->fdCacheKey = $fdCacheKey; FS::$fdCache->put($fdCacheKey, $file); } else { call_user_func($cb, $file); } }); } else { if (!$noncache) { $file->fdCacheKey = $fdCacheKey; FS::$fdCache->put($fdCacheKey, $file); } else { call_user_func($cb, $file); } } }, $path); } $mode = File::convertFlags($flags, true); $fd = fopen($path, $mode); if (!$fd) { call_user_func($cb, false); return; } $file = new File($fd); $file->path = $path; call_user_func($cb, $file); }