2016-08-24 07:01:41 +02:00
|
|
|
<?php declare(strict_types = 1);
|
2015-07-11 03:59:39 +02:00
|
|
|
|
2015-08-05 16:55:56 +02:00
|
|
|
namespace Amp\File;
|
2016-08-24 06:55:06 +02:00
|
|
|
|
|
|
|
use Interop\Async\Awaitable;
|
2016-07-21 01:33:03 +02:00
|
|
|
use Interop\Async\Loop;
|
|
|
|
|
|
|
|
const LOOP_STATE_IDENTIFIER = Driver::class;
|
2015-07-11 03:59:39 +02:00
|
|
|
|
|
|
|
/**
|
2015-07-30 15:07:01 +02:00
|
|
|
* Retrieve the application-wide filesystem instance
|
2015-07-11 03:59:39 +02:00
|
|
|
*
|
2016-07-21 01:33:03 +02:00
|
|
|
* @param \Amp\File\Driver $driver Use the specified object as the application-wide filesystem instance
|
2015-08-07 18:03:39 +02:00
|
|
|
* @return \Amp\File\Driver
|
2015-07-11 03:59:39 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function filesystem(Driver $driver = null): Driver {
|
2016-07-21 01:33:03 +02:00
|
|
|
if ($driver === null) {
|
2016-08-12 17:47:55 +02:00
|
|
|
$driver = Loop::getState(LOOP_STATE_IDENTIFIER);
|
2016-07-21 01:33:03 +02:00
|
|
|
if ($driver) {
|
|
|
|
return $driver;
|
|
|
|
}
|
|
|
|
|
|
|
|
$driver = driver();
|
2015-07-30 15:07:01 +02:00
|
|
|
}
|
2016-08-12 17:47:55 +02:00
|
|
|
Loop::setState(LOOP_STATE_IDENTIFIER, $driver);
|
2016-07-21 01:33:03 +02:00
|
|
|
return $driver;
|
2015-07-30 15:07:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-07-30 16:10:53 +02:00
|
|
|
* Create a new filesystem driver best-suited for the current environment
|
2015-07-30 15:07:01 +02:00
|
|
|
*
|
2015-08-07 18:03:39 +02:00
|
|
|
* @return \Amp\File\Driver
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function driver(): Driver {
|
2016-07-21 01:33:03 +02:00
|
|
|
$driver = Loop::get();
|
|
|
|
$loop = $driver->getHandle();
|
2016-08-24 06:55:06 +02:00
|
|
|
if (\is_resource($loop) && \get_resource_type($loop) == "uv_loop") {
|
2016-07-21 01:33:03 +02:00
|
|
|
return new UvDriver($driver);
|
2015-07-18 18:08:50 +02:00
|
|
|
} elseif (\extension_loaded("eio")) {
|
2015-07-30 16:10:53 +02:00
|
|
|
return new EioDriver;
|
2015-07-11 03:59:39 +02:00
|
|
|
} else {
|
2015-08-01 03:15:53 +02:00
|
|
|
return new BlockingDriver;
|
2015-07-11 03:59:39 +02:00
|
|
|
}
|
|
|
|
}
|
2015-07-30 15:07:01 +02:00
|
|
|
|
2015-08-13 01:02:41 +02:00
|
|
|
/**
|
|
|
|
* Open a handle for the specified path
|
|
|
|
*
|
|
|
|
* @param string $path
|
|
|
|
* @param string $mode
|
2016-08-24 06:55:06 +02:00
|
|
|
* @return \Interop\Async\Awaitable<\Amp\File\Handle>
|
2015-08-13 01:02:41 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function open(string $path, string $mode): Awaitable {
|
2015-08-13 01:02:41 +02:00
|
|
|
return filesystem()->open($path, $mode);
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:07:01 +02:00
|
|
|
/**
|
|
|
|
* Execute a file stat operation
|
|
|
|
*
|
|
|
|
* If the requested path does not exist the resulting Promise will resolve to NULL.
|
2015-08-08 16:09:07 +02:00
|
|
|
* The returned Promise whould never resolve as a failure.
|
2015-07-30 15:07:01 +02:00
|
|
|
*
|
2015-08-08 16:09:07 +02:00
|
|
|
* @param string $path An absolute file system path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<array|null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function stat(string $path): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->stat($path);
|
|
|
|
}
|
|
|
|
|
2015-08-08 16:09:07 +02:00
|
|
|
/**
|
|
|
|
* Does the specified path exist?
|
|
|
|
*
|
|
|
|
* This function should never resolve as a failure -- only a successfull bool value
|
|
|
|
* indicating the existence of the specified path.
|
|
|
|
*
|
|
|
|
* @param string $path An absolute file system path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<bool>
|
2015-08-08 16:09:07 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function exists(string $path): Awaitable {
|
2015-08-08 16:09:07 +02:00
|
|
|
return filesystem()->exists($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the size in bytes of the file at the specified path.
|
|
|
|
*
|
|
|
|
* If the path does not exist or is not a regular file this
|
|
|
|
* function's returned Promise WILL resolve as a failure.
|
|
|
|
*
|
|
|
|
* @param string $path An absolute file system path
|
|
|
|
* @fails \Amp\Files\FilesystemException If the path does not exist or is not a file
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<int>
|
2015-08-08 16:09:07 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function size(string $path): Awaitable {
|
2015-08-08 16:09:07 +02:00
|
|
|
return filesystem()->size($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Does the specified path exist and is it a directory?
|
|
|
|
*
|
|
|
|
* If the path does not exist the returned Promise will resolve
|
|
|
|
* to FALSE and will not reject with an error.
|
|
|
|
*
|
|
|
|
* @param string $path An absolute file system path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<bool>
|
2015-08-08 16:09:07 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function isdir(string $path): Awaitable {
|
2015-08-08 16:09:07 +02:00
|
|
|
return filesystem()->isdir($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Does the specified path exist and is it a file?
|
|
|
|
*
|
|
|
|
* If the path does not exist the returned Promise will resolve
|
|
|
|
* to FALSE and will not reject with an error.
|
|
|
|
*
|
|
|
|
* @param string $path An absolute file system path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<bool>
|
2015-08-08 16:09:07 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function isfile(string $path): Awaitable {
|
2015-08-08 16:09:07 +02:00
|
|
|
return filesystem()->isfile($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the path's last modification time as a unix timestamp
|
|
|
|
*
|
|
|
|
* @param string $path An absolute file system path
|
|
|
|
* @fails \Amp\Files\FilesystemException If the path does not exist
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<int>
|
2015-08-08 16:09:07 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function mtime(string $path): Awaitable {
|
2015-08-08 16:09:07 +02:00
|
|
|
return filesystem()->mtime($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the path's last access time as a unix timestamp
|
|
|
|
*
|
|
|
|
* @param string $path An absolute file system path
|
|
|
|
* @fails \Amp\Files\FilesystemException If the path does not exist
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<int>
|
2015-08-08 16:09:07 +02:00
|
|
|
*/
|
|
|
|
function atime($path) {
|
|
|
|
return filesystem()->atime($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the path's creation time as a unix timestamp
|
|
|
|
*
|
|
|
|
* @param string $path An absolute file system path
|
|
|
|
* @fails \Amp\Files\FilesystemException If the path does not exist
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<int>
|
2015-08-08 16:09:07 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function ctime(string $path): Awaitable {
|
2015-08-08 16:09:07 +02:00
|
|
|
return filesystem()->ctime($path);
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:07:01 +02:00
|
|
|
/**
|
|
|
|
* Same as stat() except if the path is a link then the link's data is returned
|
|
|
|
*
|
2015-08-08 16:09:07 +02:00
|
|
|
* If the requested path does not exist the resulting Promise will resolve to NULL.
|
|
|
|
* The returned Promise whould never resolve as a failure.
|
|
|
|
*
|
|
|
|
* @param string $path An absolute file system path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<array|null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function lstat(string $path): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->lstat($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-08-08 16:09:07 +02:00
|
|
|
* Create a symlink $link pointing to the file/directory located at $original
|
2015-07-30 15:07:01 +02:00
|
|
|
*
|
2015-08-08 16:09:07 +02:00
|
|
|
* @param string $original
|
2015-07-30 15:07:01 +02:00
|
|
|
* @param string $link
|
2015-08-08 16:09:07 +02:00
|
|
|
* @fails \Amp\Files\FilesystemException If the operation fails
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function symlink(string $original, string $link): Awaitable {
|
|
|
|
return filesystem()->symlink($original, $link);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a hard link $link pointing to the file/directory located at $original
|
|
|
|
*
|
|
|
|
* @param string $original
|
|
|
|
* @param string $link
|
|
|
|
* @fails \Amp\Files\FilesystemException If the operation fails
|
|
|
|
* @return \Interop\Async\Awaitable<null>
|
|
|
|
*/
|
|
|
|
function link(string $original, string $link): Awaitable {
|
2015-08-08 16:09:07 +02:00
|
|
|
return filesystem()->symlink($original, $link);
|
2015-07-30 15:07:01 +02:00
|
|
|
}
|
|
|
|
|
2016-08-24 06:55:06 +02:00
|
|
|
/**
|
|
|
|
* Read the symlink at $path
|
|
|
|
*
|
|
|
|
* @param string $original
|
|
|
|
* @param string $link
|
|
|
|
* @fails \Amp\Files\FilesystemException If the operation fails
|
|
|
|
* @return \Interop\Async\Awaitable<null>
|
|
|
|
*/
|
|
|
|
function readlink(string $path): Awaitable {
|
|
|
|
return filesystem()->readlink($path);
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:07:01 +02:00
|
|
|
/**
|
|
|
|
* Rename a file or directory
|
|
|
|
*
|
|
|
|
* @param string $from
|
|
|
|
* @param string $to
|
2015-08-08 16:09:07 +02:00
|
|
|
* @fails \Amp\Files\FilesystemException If the operation fails
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function rename(string $from, string $to): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->rename($from, $to);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete a file
|
|
|
|
*
|
|
|
|
* @param string $path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function unlink(string $path): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->unlink($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a director
|
|
|
|
*
|
|
|
|
* @param string $path
|
|
|
|
* @param int $mode
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function mkdir(string $path, int $mode = 0644): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->mkdir($path, $mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete a directory
|
|
|
|
*
|
2016-07-21 01:33:03 +02:00
|
|
|
* @param string $path
|
|
|
|
* @return \Interop\Async\Awaitable<null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function rmdir(string $path): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->rmdir($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve an array of files and directories inside the specified path
|
|
|
|
*
|
|
|
|
* Dot entries are not included in the resulting array (i.e. "." and "..").
|
|
|
|
*
|
|
|
|
* @param string $path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<array>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function scandir(string $path): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->scandir($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* chmod a file or directory
|
|
|
|
*
|
|
|
|
* @param string $path
|
|
|
|
* @param int $mode
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function chmod(string $path, int $mode): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->chmod($path, $mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* chown a file or directory
|
|
|
|
*
|
|
|
|
* @param string $path
|
2015-12-09 21:45:28 +01:00
|
|
|
* @param int $uid -1 to ignore
|
|
|
|
* @param int $gid -1 to ignore
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function chown(string $path, int $uid, int $gid = -1): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->chown($path, $uid, $gid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the access and modification time of the specified path
|
|
|
|
*
|
|
|
|
* If the file does not exist it will be created automatically.
|
|
|
|
*
|
|
|
|
* @param string $path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<null>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function touch(string $path): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->touch($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Buffer the specified file's contents
|
|
|
|
*
|
|
|
|
* @param string $path The file path from which to buffer contents
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable<string>
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function get(string $path): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->get($path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write the contents string to the specified path.
|
|
|
|
*
|
|
|
|
* @param string $path The file path to which to $contents should be written
|
|
|
|
* @param string $contents The data to write to the specified $path
|
2016-07-21 01:33:03 +02:00
|
|
|
* @return \Interop\Async\Awaitable A promise resolving to the integer length written upon success
|
2015-07-30 15:07:01 +02:00
|
|
|
*/
|
2016-08-24 06:55:06 +02:00
|
|
|
function put(string $path, string $contents): Awaitable {
|
2015-07-30 15:07:01 +02:00
|
|
|
return filesystem()->put($path, $contents);
|
|
|
|
}
|