/** * Open file * @param string $path Path * @param string $flags Flags * @param callable $cb Callback (File) * @param integer $mode Mode (see EIO_S_I* constants) * @param integer $pri Priority * @return resource */ public static function open($path, $flags, $cb, $mode = null, $pri = EIO_PRI_DEFAULT) { $cb = CallbackWrapper::forceWrap($cb); if (!FileSystem::$supported) { $mode = File::convertFlags($flags, true); $fd = fopen($path, $mode); if (!$fd) { call_user_func($cb, false); return false; } $file = new File($fd, $path); call_user_func($cb, $file); return true; } $fdCacheKey = $path . "" . $flags; $noncache = strpos($flags, '!') !== false; $flags = File::convertFlags($flags); if (!$noncache && ($item = FileSystem::$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 null; } elseif (!$noncache) { $item = FileSystem::$fdCache->put($fdCacheKey, null); $item->addListener($cb); } return eio_open($path, $flags, $mode, $pri, function ($path, $fd) use($cb, $flags, $fdCacheKey, $noncache) { if ($fd === -1) { if ($noncache) { call_user_func($cb, false); } else { FileSystem::$fdCache->put($fdCacheKey, false, self::$badFDttl); } return; } $file = new File($fd, $path); $file->append = ($flags | EIO_O_APPEND) === $flags; if ($file->append) { $file->stat(function ($file, $stat) use($cb, $noncache, $fdCacheKey) { $file->offset = $stat['size']; if (!$noncache) { $file->fdCacheKey = $fdCacheKey; FileSystem::$fdCache->put($fdCacheKey, $file); } else { call_user_func($cb, $file); } }); } else { if (!$noncache) { $file->fdCacheKey = $fdCacheKey; FileSystem::$fdCache->put($fdCacheKey, $file); } else { call_user_func($cb, $file); } } }, $path); }