20 enum class UVFsType: std::underlying_type_t<uv_fs_type> {
21 UNKNOWN = UV_FS_UNKNOWN,
22 CUSTOM = UV_FS_CUSTOM,
27 SENDFILE = UV_FS_SENDFILE,
31 FTRUNCATE = UV_FS_FTRUNCATE,
33 FUTIME = UV_FS_FUTIME,
34 ACCESS = UV_FS_ACCESS,
36 FCHMOD = UV_FS_FCHMOD,
38 FDATASYNC = UV_FS_FDATASYNC,
39 UNLINK = UV_FS_UNLINK,
42 MKDTEMP = UV_FS_MKDTEMP,
43 RENAME = UV_FS_RENAME,
44 SCANDIR = UV_FS_SCANDIR,
46 SYMLINK = UV_FS_SYMLINK,
47 READLINK = UV_FS_READLINK,
49 FCHOWN = UV_FS_FCHOWN,
50 REALPATH = UV_FS_REALPATH,
51 COPYFILE = UV_FS_COPYFILE
55 enum class UVDirentTypeT: std::underlying_type_t<uv_dirent_type_t> {
56 UNKNOWN = UV_DIRENT_UNKNOWN,
57 FILE = UV_DIRENT_FILE,
59 LINK = UV_DIRENT_LINK,
60 FIFO = UV_DIRENT_FIFO,
61 SOCKET = UV_DIRENT_SOCKET,
62 CHAR = UV_DIRENT_CHAR,
63 BLOCK = UV_DIRENT_BLOCK
67 enum class UVCopyFileFlags: int {
68 EXCL = UV_FS_COPYFILE_EXCL
72 enum class UVSymLinkFlags: int {
73 DIR = UV_FS_SYMLINK_DIR,
74 JUNCTION = UV_FS_SYMLINK_JUNCTION
125 template<details::UVFsType e>
127 FsEvent(
const char *pathname) noexcept: path{pathname} {}
141 FsEvent(
const char *pathname, std::unique_ptr<
const char[]> buf, std::size_t sz) noexcept
142 : path{pathname}, data{std::move(buf)}, size{sz}
146 std::unique_ptr<const char[]>
data;
159 FsEvent(
const char *pathname, std::size_t sz) noexcept
160 : path{pathname}, size{sz}
176 FsEvent(
const char *pathname, std::size_t sz) noexcept
177 : path{pathname}, size{sz}
194 : path{pathname}, stat{std::move(curr)}
211 : path{pathname}, stat{std::move(curr)}
228 : path{pathname}, stat{std::move(curr)}
244 FsEvent(
const char *pathname, std::size_t sz) noexcept
245 : path{pathname}, size{sz}
261 explicit FsEvent(
const char *pathname,
const char *buf, std::size_t sz) noexcept
262 : path{pathname}, data{buf}, size{sz}
279 template<details::UVFsType e>
280 static void fsGenericCallback(uv_fs_t *req) {
281 auto ptr = Request<T, uv_fs_t>::reserve(req);
282 if(req->result < 0) { ptr->publish(
ErrorEvent{req->result}); }
286 template<details::UVFsType e>
287 static void fsResultCallback(uv_fs_t *req) {
288 auto ptr = Request<T, uv_fs_t>::reserve(req);
289 if(req->result < 0) { ptr->publish(
ErrorEvent{req->result}); }
290 else { ptr->publish(
FsEvent<e>{req->
path,
static_cast<std::size_t
>(req->result)}); }
293 template<details::UVFsType e>
294 static void fsStatCallback(uv_fs_t *req) {
295 auto ptr = Request<T, uv_fs_t>::reserve(req);
296 if(req->result < 0) { ptr->publish(
ErrorEvent{req->result}); }
300 template<
typename... Args>
301 void cleanupAndInvoke(Args&&... args) {
302 uv_fs_req_cleanup(this->
get());
303 this->invoke(std::forward<Args>(args)...);
306 template<
typename F,
typename... Args>
307 void cleanupAndInvokeSync(F &&f, Args&&... args) {
308 uv_fs_req_cleanup(this->
get());
309 std::forward<F>(f)(std::forward<Args>(args)...,
nullptr);
313 using Time = std::chrono::duration<double>;
314 using Type = details::UVFsType;
315 using EntryType = details::UVDirentTypeT;
316 using Entry = std::pair<EntryType, std::string>;
318 using Request<T, uv_fs_t>::Request;
335 static constexpr uv_file BAD_FD = -1;
337 static void fsOpenCallback(uv_fs_t *req) {
338 auto ptr = reserve(req);
340 if(req->result < 0) {
343 ptr->file =
static_cast<uv_file
>(req->result);
348 static void fsCloseCallback(uv_fs_t *req) {
349 auto ptr = reserve(req);
351 if(req->result < 0) {
359 static void fsReadCallback(uv_fs_t *req) {
360 auto ptr = reserve(req);
361 if(req->result < 0) { ptr->publish(
ErrorEvent{req->result}); }
362 else { ptr->publish(
FsEvent<Type::READ>{req->
path, std::move(ptr->data),
static_cast<std::size_t
>(req->result)}); }
366 using FsRequest::FsRequest;
369 uv_fs_req_cleanup(
get());
379 cleanupAndInvoke(&uv_fs_close, parent(),
get(), file, &fsCloseCallback);
388 cleanupAndInvokeSync(&uv_fs_close, parent(), req, file);
389 if(req->result >= 0) { file = BAD_FD; }
390 return !(req->result < 0);
403 void open(std::string path,
int flags,
int mode) {
404 cleanupAndInvoke(&uv_fs_open, parent(),
get(), path.data(), flags, mode, &fsOpenCallback);
414 bool openSync(std::string path,
int flags,
int mode) {
416 cleanupAndInvokeSync(&uv_fs_open, parent(), req, path.data(), flags, mode);
417 if(req->result >= 0) { file =
static_cast<uv_file
>(req->result); }
418 return !(req->result < 0);
430 void read(int64_t offset,
unsigned int len) {
431 data = std::unique_ptr<char[]>{
new char[len]};
432 buffer = uv_buf_init(data.get(), len);
433 uv_buf_t bufs[] = { buffer };
434 cleanupAndInvoke(&uv_fs_read, parent(),
get(), file, bufs, 1, offset, &fsReadCallback);
449 std::pair<bool, std::pair<std::unique_ptr<const char[]>, std::size_t>>
451 data = std::unique_ptr<char[]>{
new char[len]};
452 buffer = uv_buf_init(data.get(), len);
453 uv_buf_t bufs[] = { buffer };
455 cleanupAndInvokeSync(&uv_fs_read, parent(), req, file, bufs, 1, offset);
456 bool err = req->result < 0;
457 return std::make_pair(!err, std::make_pair(std::move(data), err ? 0 : std::size_t(req->result)));
473 void write(std::unique_ptr<
char[]> buf,
unsigned int len, int64_t offset) {
474 this->data = std::move(buf);
475 uv_buf_t bufs[] = { uv_buf_init(this->data.get(), len) };
476 cleanupAndInvoke(&uv_fs_write, parent(),
get(), file, bufs, 1, offset, &fsResultCallback<Type::WRITE>);
492 void write(
char *buf,
unsigned int len, int64_t offset) {
493 uv_buf_t bufs[] = { uv_buf_init(buf, len) };
494 cleanupAndInvoke(&uv_fs_write, parent(),
get(), file, bufs, 1, offset, &fsResultCallback<Type::WRITE>);
508 std::pair<bool, std::size_t>
writeSync(std::unique_ptr<
char[]> buf,
unsigned int len, int64_t offset) {
509 this->data = std::move(buf);
510 uv_buf_t bufs[] = { uv_buf_init(this->data.get(), len) };
512 cleanupAndInvokeSync(&uv_fs_write, parent(), req, file, bufs, 1, offset);
513 bool err = req->result < 0;
514 return std::make_pair(!err, err ? 0 : std::size_t(req->result));
524 cleanupAndInvoke(&uv_fs_fstat, parent(),
get(), file, &fsStatCallback<Type::FSTAT>);
536 cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file);
537 return std::make_pair(!(req->result < 0), req->statbuf);
547 cleanupAndInvoke(&uv_fs_fsync, parent(),
get(), file, &fsGenericCallback<Type::FSYNC>);
556 cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file);
557 return !(req->result < 0);
567 cleanupAndInvoke(&uv_fs_fdatasync, parent(),
get(), file, &fsGenericCallback<Type::FDATASYNC>);
576 cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file);
577 return !(req->result < 0);
589 cleanupAndInvoke(&uv_fs_ftruncate, parent(),
get(), file, offset, &fsGenericCallback<Type::FTRUNCATE>);
599 cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset);
600 return !(req->result < 0);
614 cleanupAndInvoke(&uv_fs_sendfile, parent(),
get(), out, file, offset, length, &fsResultCallback<Type::SENDFILE>);
630 cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, file, offset, length);
631 bool err = req->result < 0;
632 return std::make_pair(!err, err ? 0 : std::size_t(req->result));
644 cleanupAndInvoke(&uv_fs_fchmod, parent(),
get(), file, mode, &fsGenericCallback<Type::FCHMOD>);
654 cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode);
655 return !(req->result < 0);
669 void utime(Time atime, Time mtime) {
670 cleanupAndInvoke(&uv_fs_futime, parent(),
get(), file, atime.count(), mtime.count(), &fsGenericCallback<Type::FUTIME>);
683 cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count());
684 return !(req->result < 0);
697 cleanupAndInvoke(&uv_fs_fchown, parent(),
get(), file, uid, gid, &fsGenericCallback<Type::FCHOWN>);
708 cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid);
709 return !(req->result < 0);
723 return uv_get_osfhandle(file);
737 std::unique_ptr<char[]> data{
nullptr};
739 uv_file file{BAD_FD};
756 static void fsReadlinkCallback(uv_fs_t *req) {
757 auto ptr = reserve(req);
758 if(req->result < 0) { ptr->publish(
ErrorEvent{req->result}); }
763 using CopyFile = details::UVCopyFileFlags;
764 using SymLink = details::UVSymLinkFlags;
766 using FsRequest::FsRequest;
769 uv_fs_req_cleanup(
get());
781 cleanupAndInvoke(&uv_fs_unlink, parent(),
get(), path.data(), &fsGenericCallback<Type::UNLINK>);
791 cleanupAndInvokeSync(&uv_fs_unlink, parent(), req, path.data());
792 return !(req->result < 0);
804 void mkdir(std::string path,
int mode) {
805 cleanupAndInvoke(&uv_fs_mkdir, parent(),
get(), path.data(), mode, &fsGenericCallback<Type::MKDIR>);
816 cleanupAndInvokeSync(&uv_fs_mkdir, parent(), req, path.data(), mode);
817 return !(req->result < 0);
829 cleanupAndInvoke(&uv_fs_mkdtemp, parent(),
get(), tpl.data(), &fsGenericCallback<Type::MKDTEMP>);
843 cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), req, tpl.data());
844 return std::make_pair(!(req->result < 0), req->path);
856 cleanupAndInvoke(&uv_fs_rmdir, parent(),
get(), path.data(), &fsGenericCallback<Type::RMDIR>);
866 cleanupAndInvokeSync(&uv_fs_rmdir, parent(), req, path.data());
867 return !(req->result < 0);
880 cleanupAndInvoke(&uv_fs_scandir, parent(),
get(), path.data(), flags, &fsResultCallback<Type::SCANDIR>);
893 std::pair<bool, std::size_t>
scandirSync(std::string path,
int flags) {
895 cleanupAndInvokeSync(&uv_fs_scandir, parent(), req, path.data(), flags);
896 bool err = req->result < 0;
897 return std::make_pair(!err, err ? 0 : std::size_t(req->result));
931 std::pair<bool, Entry> ret{
false, { EntryType::UNKNOWN,
"" }};
932 auto res = uv_fs_scandir_next(
get(), &dirent);
935 ret.second.first =
static_cast<EntryType
>(dirent.type);
936 ret.second.second = dirent.name;
952 cleanupAndInvoke(&uv_fs_stat, parent(),
get(), path.data(), &fsStatCallback<Type::STAT>);
966 cleanupAndInvokeSync(&uv_fs_stat, parent(), req, path.data());
967 return std::make_pair(!(req->result < 0), req->statbuf);
979 cleanupAndInvoke(&uv_fs_lstat, parent(),
get(), path.data(), &fsStatCallback<Type::LSTAT>);
993 cleanupAndInvokeSync(&uv_fs_lstat, parent(), req, path.data());
994 return std::make_pair(!(req->result < 0), req->statbuf);
1006 void rename(std::string old, std::string path) {
1007 cleanupAndInvoke(&uv_fs_rename, parent(),
get(), old.data(), path.data(), &fsGenericCallback<Type::RENAME>);
1018 cleanupAndInvokeSync(&uv_fs_rename, parent(), req, old.data(), path.data());
1019 return !(req->result < 0);
1045 cleanupAndInvoke(&uv_fs_copyfile, parent(),
get(), old.data(), path.data(), flags, &fsGenericCallback<Type::COPYFILE>);
1069 cleanupAndInvokeSync(&uv_fs_copyfile, parent(),
get(), old.data(), path.data(), flags);
1070 return !(req->result < 0);
1083 cleanupAndInvoke(&uv_fs_access, parent(),
get(), path.data(), mode, &fsGenericCallback<Type::ACCESS>);
1094 cleanupAndInvokeSync(&uv_fs_access, parent(), req, path.data(), mode);
1095 return !(req->result < 0);
1107 void chmod(std::string path,
int mode) {
1108 cleanupAndInvoke(&uv_fs_chmod, parent(),
get(), path.data(), mode, &fsGenericCallback<Type::CHMOD>);
1119 cleanupAndInvokeSync(&uv_fs_chmod, parent(), req, path.data(), mode);
1120 return !(req->result < 0);
1135 void utime(std::string path, Time atime, Time mtime) {
1136 cleanupAndInvoke(&uv_fs_utime, parent(),
get(), path.data(), atime.count(), mtime.count(), &fsGenericCallback<Type::UTIME>);
1150 cleanupAndInvokeSync(&uv_fs_utime, parent(), req, path.data(), atime.count(), mtime.count());
1151 return !(req->result < 0);
1163 void link(std::string old, std::string path) {
1164 cleanupAndInvoke(&uv_fs_link, parent(),
get(), old.data(), path.data(), &fsGenericCallback<Type::LINK>);
1175 cleanupAndInvokeSync(&uv_fs_link, parent(), req, old.data(), path.data());
1176 return !(req->result < 0);
1197 cleanupAndInvoke(&uv_fs_symlink, parent(),
get(), old.data(), path.data(), flags, &fsGenericCallback<Type::SYMLINK>);
1217 cleanupAndInvokeSync(&uv_fs_symlink, parent(), req, old.data(), path.data(), flags);
1218 return !(req->result < 0);
1230 cleanupAndInvoke(&uv_fs_readlink, parent(),
get(), path.data(), &fsReadlinkCallback);
1244 std::pair<bool, std::pair<const char *, std::size_t>>
1247 cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data());
1248 bool err = req->result < 0;
1249 return std::make_pair(!err, std::make_pair(static_cast<char *>(req->ptr), err ? 0 : std::size_t(req->result)));
1261 cleanupAndInvoke(&uv_fs_realpath, parent(),
get(), path.data(), &fsGenericCallback<Type::REALPATH>);
1275 cleanupAndInvokeSync(&uv_fs_realpath, parent(), req, path.data());
1276 return std::make_pair(!(req->result < 0), req->path);
1290 cleanupAndInvoke(&uv_fs_chown, parent(),
get(), path.data(), uid, gid, &fsGenericCallback<Type::CHOWN>);
1302 cleanupAndInvokeSync(&uv_fs_chown, parent(), req, path.data(), uid, gid);
1303 return !(req->result < 0);
void utime(std::string path, Time atime, Time mtime)
Async utime.
void symlink(std::string old, std::string path, Flags< SymLink > flags=Flags< SymLink >{})
Async symlink.
bool truncateSync(int64_t offset)
Sync ftruncate.
bool unlinkSync(std::string path)
Sync unlink.
void chown(Uid uid, Gid gid)
Async fchown.
std::pair< bool, std::pair< const char *, std::size_t > > readlinkSync(std::string path)
Sync readlink.
void access(std::string path, int mode)
Async access.
bool datasyncSync()
Sync fdatasync.
details::UVTypeWrapper< uv_file > FileHandle
bool accessSync(std::string path, int mode)
Sync access.
std::pair< bool, Stat > statSync(std::string path)
Sync stat.
void chmod(std::string path, int mode)
Async chmod.
bool utimeSync(Time atime, Time mtime)
Sync futime.
void rmdir(std::string path)
Async rmdir.
bool chmodSync(std::string path, int mode)
Sync chmod.
std::pair< bool, Stat > lstatSync(std::string path)
Sync lstat.
bool utimeSync(std::string path, Time atime, Time mtime)
Sync utime.
std::unique_ptr< const char[]> data
Base class for FsReq and/or FileReq.
bool mkdirSync(std::string path, int mode)
Sync mkdir.
void open(std::string path, int flags, int mode)
Async open.
details::UVTypeWrapper< uv_os_fd_t > OSFileDescriptor
std::pair< bool, const char * > realpathSync(std::string path)
Sync realpath.
void write(std::unique_ptr< char[]> buf, unsigned int len, int64_t offset)
Async write.
bool chownSync(std::string path, Uid uid, Gid gid)
Sync chown.
void chmod(int mode)
Async fchmod.
void rename(std::string old, std::string path)
Async rename.
void scandir(std::string path, int flags)
Async scandir.
std::pair< bool, Entry > scandirNext()
Gets entries populated with the next directory entry data.
Utility class to handle flags.
std::pair< bool, const char * > mkdtempSync(std::string tpl)
Sync mktemp.
bool symlinkSync(std::string old, std::string path, Flags< SymLink > flags=Flags< SymLink >{})
Sync symlink.
void mkdir(std::string path, int mode)
Async mkdir.
void unlink(std::string path)
Async unlink.
std::pair< bool, Stat > statSync()
Sync fstat.
bool openSync(std::string path, int flags, int mode)
Sync open.
std::pair< bool, std::size_t > writeSync(std::unique_ptr< char[]> buf, unsigned int len, int64_t offset)
Sync write.
bool syncSync()
Sync fsync.
void utime(Time atime, Time mtime)
Async futime.
bool rmdirSync(std::string path)
Sync rmdir.
void datasync()
Async fdatasync.
void readlink(std::string path)
Async readlink.
bool closeSync()
Sync close.
std::pair< bool, std::pair< std::unique_ptr< const char[]>, std::size_t > > readSync(int64_t offset, unsigned int len)
Sync read.
bool chmodSync(int mode)
Sync fchmod.
void lstat(std::string path)
Async lstat.
std::pair< bool, std::size_t > sendfileSync(FileHandle out, int64_t offset, std::size_t length)
Sync sendfile.
void mkdtemp(std::string tpl)
Async mktemp.
void link(std::string old, std::string path)
Async link.
void chown(std::string path, Uid uid, Gid gid)
Async chown.
bool renameSync(std::string old, std::string path)
Sync rename.
void truncate(int64_t offset)
Async ftruncate.
bool linkSync(std::string old, std::string path)
Sync link.
void realpath(std::string path)
Async realpath.
void copyfile(std::string old, std::string path, Flags< CopyFile > flags=Flags< CopyFile >{})
Copies a file asynchronously from a path to a new one.
OSFileDescriptor handle() const noexcept
Gets the OS dependent handle.
void read(int64_t offset, unsigned int len)
Async read.
void write(char *buf, unsigned int len, int64_t offset)
Async write.
void stat(std::string path)
Async stat.
bool copyfileSync(std::string old, std::string path, Flags< CopyFile > flags=Flags< CopyFile >{})
Copies a file synchronously from a path to a new one.
void sendfile(FileHandle out, int64_t offset, std::size_t length)
Async sendfile.
std::pair< bool, std::size_t > scandirSync(std::string path, int flags)
Sync scandir.
bool chownSync(Uid uid, Gid gid)
Sync fchown.