uvw  2.11.0
fs.h
1 #ifndef UVW_FS_INCLUDE_H
2 #define UVW_FS_INCLUDE_H
3 
4 
5 #include <utility>
6 #include <memory>
7 #include <string>
8 #include <chrono>
9 #include <uv.h>
10 #include "request.hpp"
11 #include "util.h"
12 #include "loop.h"
13 
14 
15 namespace uvw {
16 
17 
18 namespace details {
19 
20 
21 enum class UVFsType: std::underlying_type_t<uv_fs_type> {
22  UNKNOWN = UV_FS_UNKNOWN,
23  CUSTOM = UV_FS_CUSTOM,
24  OPEN = UV_FS_OPEN,
25  CLOSE = UV_FS_CLOSE,
26  READ = UV_FS_READ,
27  WRITE = UV_FS_WRITE,
28  SENDFILE = UV_FS_SENDFILE,
29  STAT = UV_FS_STAT,
30  LSTAT = UV_FS_LSTAT,
31  FSTAT = UV_FS_FSTAT,
32  FTRUNCATE = UV_FS_FTRUNCATE,
33  UTIME = UV_FS_UTIME,
34  FUTIME = UV_FS_FUTIME,
35  ACCESS = UV_FS_ACCESS,
36  CHMOD = UV_FS_CHMOD,
37  FCHMOD = UV_FS_FCHMOD,
38  FSYNC = UV_FS_FSYNC,
39  FDATASYNC = UV_FS_FDATASYNC,
40  UNLINK = UV_FS_UNLINK,
41  RMDIR = UV_FS_RMDIR,
42  MKDIR = UV_FS_MKDIR,
43  MKDTEMP = UV_FS_MKDTEMP,
44  RENAME = UV_FS_RENAME,
45  SCANDIR = UV_FS_SCANDIR,
46  LINK = UV_FS_LINK,
47  SYMLINK = UV_FS_SYMLINK,
48  READLINK = UV_FS_READLINK,
49  CHOWN = UV_FS_CHOWN,
50  FCHOWN = UV_FS_FCHOWN,
51  REALPATH = UV_FS_REALPATH,
52  COPYFILE = UV_FS_COPYFILE,
53  LCHOWN = UV_FS_LCHOWN,
54  OPENDIR = UV_FS_OPENDIR,
55  READDIR = UV_FS_READDIR,
56  CLOSEDIR = UV_FS_CLOSEDIR,
57  STATFS = UV_FS_STATFS,
58  MKSTEMP = UV_FS_MKSTEMP,
59  LUTIME = UV_FS_LUTIME
60 };
61 
62 
63 enum class UVDirentTypeT: std::underlying_type_t<uv_dirent_type_t> {
64  UNKNOWN = UV_DIRENT_UNKNOWN,
65  FILE = UV_DIRENT_FILE,
66  DIR = UV_DIRENT_DIR,
67  LINK = UV_DIRENT_LINK,
68  FIFO = UV_DIRENT_FIFO,
69  SOCKET = UV_DIRENT_SOCKET,
70  CHAR = UV_DIRENT_CHAR,
71  BLOCK = UV_DIRENT_BLOCK
72 };
73 
74 
75 enum class UVFileOpenFlags: int {
76  APPEND = UV_FS_O_APPEND,
77  CREAT = UV_FS_O_CREAT,
78  DIRECT = UV_FS_O_DIRECT,
79  DIRECTORY = UV_FS_O_DIRECTORY,
80  DSYNC = UV_FS_O_DSYNC,
81  EXCL = UV_FS_O_EXCL,
82  EXLOCK = UV_FS_O_EXLOCK,
83  FILEMAP = UV_FS_O_FILEMAP,
84  NOATIME = UV_FS_O_NOATIME,
85  NOCTTY = UV_FS_O_NOCTTY,
86  NOFOLLOW = UV_FS_O_NOFOLLOW,
87  NONBLOCK = UV_FS_O_NONBLOCK,
88  RANDOM = UV_FS_O_RANDOM,
89  RDONLY = UV_FS_O_RDONLY,
90  RDWR = UV_FS_O_RDWR,
91  SEQUENTIAL = UV_FS_O_SEQUENTIAL,
92  SHORT_LIVED = UV_FS_O_SHORT_LIVED,
93  SYMLINK = UV_FS_O_SYMLINK,
94  SYNC = UV_FS_O_SYNC,
95  TEMPORARY = UV_FS_O_TEMPORARY,
96  TRUNC = UV_FS_O_TRUNC,
97  WRONLY = UV_FS_O_WRONLY
98 };
99 
100 
101 enum class UVCopyFileFlags: int {
102  EXCL = UV_FS_COPYFILE_EXCL,
103  FICLONE = UV_FS_COPYFILE_FICLONE,
104  FICLONE_FORCE = UV_FS_COPYFILE_FICLONE_FORCE
105 };
106 
107 
108 enum class UVSymLinkFlags: int {
109  DIR = UV_FS_SYMLINK_DIR,
110  JUNCTION = UV_FS_SYMLINK_JUNCTION
111 };
112 
113 
114 }
115 
116 
168 template<details::UVFsType e>
169 struct FsEvent {
170  FsEvent(const char *pathname) noexcept: path{pathname} {}
171 
172  const char * path;
173 };
174 
175 
182 template<>
183 struct FsEvent<details::UVFsType::READ> {
184  FsEvent(const char *pathname, std::unique_ptr<const char[]> buf, std::size_t sz) noexcept
185  : path{pathname}, data{std::move(buf)}, size{sz}
186  {}
187 
188  const char * path;
189  std::unique_ptr<const char[]> data;
190  std::size_t size;
191 };
192 
193 
200 template<>
201 struct FsEvent<details::UVFsType::WRITE> {
202  FsEvent(const char *pathname, std::size_t sz) noexcept
203  : path{pathname}, size{sz}
204  {}
205 
206  const char * path;
207  std::size_t size;
208 };
209 
210 
217 template<>
218 struct FsEvent<details::UVFsType::SENDFILE> {
219  FsEvent(const char *pathname, std::size_t sz) noexcept
220  : path{pathname}, size{sz}
221  {}
222 
223  const char * path;
224  std::size_t size;
225 };
226 
227 
234 template<>
235 struct FsEvent<details::UVFsType::STAT> {
236  FsEvent(const char *pathname, Stat curr) noexcept
237  : path{pathname}, stat{std::move(curr)}
238  {}
239 
240  const char * path;
242 };
243 
244 
251 template<>
252 struct FsEvent<details::UVFsType::FSTAT> {
253  FsEvent(const char *pathname, Stat curr) noexcept
254  : path{pathname}, stat{std::move(curr)}
255  {}
256 
257  const char * path;
259 };
260 
261 
268 template<>
269 struct FsEvent<details::UVFsType::LSTAT> {
270  FsEvent(const char *pathname, Stat curr) noexcept
271  : path{pathname}, stat{std::move(curr)}
272  {}
273 
274  const char * path;
276 };
277 
278 
285 template<>
286 struct FsEvent<details::UVFsType::STATFS> {
287  FsEvent(const char *pathname, Statfs curr) noexcept
288  : path{pathname}, statfs{std::move(curr)}
289  {}
290 
291  const char * path;
293 };
294 
295 
302 template<>
303 struct FsEvent<details::UVFsType::MKSTEMP> {
304  FsEvent(const char *pathname, std::size_t desc) noexcept
305  : path{pathname}, descriptor{desc}
306  {}
307 
308  const char * path;
309  std::size_t descriptor;
310 };
311 
312 
319 template<>
320 struct FsEvent<details::UVFsType::SCANDIR> {
321  FsEvent(const char *pathname, std::size_t sz) noexcept
322  : path{pathname}, size{sz}
323  {}
324 
325  const char * path;
326  std::size_t size;
327 };
328 
329 
336 template<>
337 struct FsEvent<details::UVFsType::READLINK> {
338  explicit FsEvent(const char *pathname, const char *buf, std::size_t sz) noexcept
339  : path{pathname}, data{buf}, size{sz}
340  {}
341 
342  const char * path;
343  const char * data;
344  std::size_t size;
345 };
346 
347 
354 template<>
355 struct FsEvent<details::UVFsType::READDIR> {
356  using EntryType = details::UVDirentTypeT;
357 
358  FsEvent(const char *name, EntryType type, bool eos) noexcept
359  : name{name}, type{type}, eos{eos}
360  {}
361 
362  const char * name;
363  EntryType type;
364  bool eos;
365 };
366 
367 
373 template<typename T>
374 class FsRequest: public Request<T, uv_fs_t> {
375 protected:
376  template<details::UVFsType e>
377  static void fsGenericCallback(uv_fs_t *req) {
378  auto ptr = Request<T, uv_fs_t>::reserve(req);
379  if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
380  else { ptr->publish(FsEvent<e>{req->path}); }
381  }
382 
383  template<details::UVFsType e>
384  static void fsResultCallback(uv_fs_t *req) {
385  auto ptr = Request<T, uv_fs_t>::reserve(req);
386  if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
387  else { ptr->publish(FsEvent<e>{req->path, static_cast<std::size_t>(req->result)}); }
388  }
389 
390  template<details::UVFsType e>
391  static void fsStatCallback(uv_fs_t *req) {
392  auto ptr = Request<T, uv_fs_t>::reserve(req);
393  if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
394  else { ptr->publish(FsEvent<e>{req->path, req->statbuf}); }
395  }
396 
397  static void fsStatfsCallback(uv_fs_t *req) {
398  auto ptr = Request<T, uv_fs_t>::reserve(req);
399  if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
400  else { ptr->publish(FsEvent<Type::STATFS>{req->path, *static_cast<Statfs *>(req->ptr)}); }
401  }
402 
403  template<typename... Args>
404  void cleanupAndInvoke(Args&&... args) {
405  uv_fs_req_cleanup(this->get());
406  this->invoke(std::forward<Args>(args)...);
407  }
408 
409  template<typename F, typename... Args>
410  void cleanupAndInvokeSync(F &&f, Args&&... args) {
411  uv_fs_req_cleanup(this->get());
412  std::forward<F>(f)(std::forward<Args>(args)..., nullptr);
413  }
414 
415 public:
416  using Time = std::chrono::duration<double>;
417  using Type = details::UVFsType;
418  using EntryType = details::UVDirentTypeT;
419 
421 };
422 
423 
436 class FileReq final: public FsRequest<FileReq> {
437  static constexpr uv_file BAD_FD = -1;
438 
439  static void fsOpenCallback(uv_fs_t *req);
440  static void fsCloseCallback(uv_fs_t *req);
441  static void fsReadCallback(uv_fs_t *req);
442 
443 public:
444  using FileOpen = details::UVFileOpenFlags;
445 
446  using FsRequest::FsRequest;
447 
448  ~FileReq() noexcept;
449 
456  void close();
457 
462  bool closeSync();
463 
503  void open(const std::string &path, Flags<FileOpen> flags, int mode);
504 
542  bool openSync(const std::string &path, Flags<FileOpen> flags, int mode);
543 
553  void read(int64_t offset, unsigned int len);
554 
567  std::pair<bool, std::pair<std::unique_ptr<const char[]>, std::size_t>> readSync(int64_t offset, unsigned int len);
568 
582  void write(std::unique_ptr<char[]> buf, unsigned int len, int64_t offset);
583 
597  void write(char *buf, unsigned int len, int64_t offset);
598 
610  std::pair<bool, std::size_t> writeSync(std::unique_ptr<char[]> buf, unsigned int len, int64_t offset);
611 
618  void stat();
619 
627  std::pair<bool, Stat> statSync();
628 
635  void sync();
636 
641  bool syncSync();
642 
649  void datasync();
650 
655  bool datasyncSync();
656 
665  void truncate(int64_t offset);
666 
672  bool truncateSync(int64_t offset);
673 
684  void sendfile(FileHandle out, int64_t offset, std::size_t length);
685 
697  std::pair<bool, std::size_t> sendfileSync(FileHandle out, int64_t offset, std::size_t length);
698 
707  void chmod(int mode);
708 
714  bool chmodSync(int mode);
715 
727  void futime(Time atime, Time mtime);
728 
737  bool futimeSync(Time atime, Time mtime);
738 
748  void chown(Uid uid, Gid gid);
749 
756  bool chownSync(Uid uid, Gid gid);
757 
766  operator FileHandle() const noexcept;
767 
768 private:
769  std::unique_ptr<char[]> current{nullptr};
770  uv_buf_t buffer{};
771  uv_file file{BAD_FD};
772 };
773 
774 
787 class FsReq final: public FsRequest<FsReq> {
788  static void fsReadlinkCallback(uv_fs_t *req);
789  static void fsReaddirCallback(uv_fs_t *req);
790 
791 public:
792  using CopyFile = details::UVCopyFileFlags;
793  using SymLink = details::UVSymLinkFlags;
794 
795  using FsRequest::FsRequest;
796 
797  ~FsReq() noexcept;
798 
807  void unlink(const std::string &path);
808 
814  bool unlinkSync(const std::string &path);
815 
825  void mkdir(const std::string &path, int mode);
826 
833  bool mkdirSync(const std::string &path, int mode);
834 
843  void mkdtemp(const std::string &tpl);
844 
854  std::pair<bool, const char *> mkdtempSync(const std::string &tpl);
855 
864  void mkstemp(const std::string &tpl);
865 
886  std::pair<bool, std::pair<std::string, std::size_t>> mkstempSync(const std::string &tpl);
887 
900  void lutime(const std::string &path, Time atime, Time mtime);
901 
911  bool lutimeSync(const std::string &path, Time atime, Time mtime);
912 
921  void rmdir(const std::string &path);
922 
928  bool rmdirSync(const std::string &path);
929 
939  void scandir(const std::string &path, int flags);
940 
951  std::pair<bool, std::size_t> scandirSync(const std::string &path, int flags);
952 
982  std::pair<bool, std::pair<EntryType, const char *>> scandirNext();
983 
992  void stat(const std::string &path);
993 
1003  std::pair<bool, Stat> statSync(const std::string &path);
1004 
1013  void lstat(const std::string &path);
1014 
1024  std::pair<bool, Stat> lstatSync(const std::string &path);
1025 
1037  void statfs(const std::string &path);
1038 
1051  std::pair<bool, Statfs> statfsSync(const std::string &path);
1052 
1062  void rename(const std::string &old, const std::string &path);
1063 
1070  bool renameSync(const std::string &old, const std::string &path);
1071 
1101  void copyfile(const std::string &old, const std::string &path, Flags<CopyFile> flags = Flags<CopyFile>{});
1102 
1122  bool copyfileSync(const std::string &old, const std::string &path, Flags<CopyFile> flags = Flags<CopyFile>{});
1123 
1133  void access(const std::string &path, int mode);
1134 
1141  bool accessSync(const std::string &path, int mode);
1142 
1152  void chmod(const std::string &path, int mode);
1153 
1160  bool chmodSync(const std::string &path, int mode);
1161 
1174  void utime(const std::string &path, Time atime, Time mtime);
1175 
1185  bool utimeSync(const std::string &path, Time atime, Time mtime);
1186 
1196  void link(const std::string &old, const std::string &path);
1197 
1204  bool linkSync(const std::string &old, const std::string &path);
1205 
1223  void symlink(const std::string &old, const std::string &path, Flags<SymLink> flags = Flags<SymLink>{});
1224 
1240  bool symlinkSync(const std::string &old, const std::string &path, Flags<SymLink> flags = Flags<SymLink>{});
1241 
1250  void readlink(const std::string &path);
1251 
1263  std::pair<bool, std::pair<const char *, std::size_t>> readlinkSync(const std::string &path);
1264 
1273  void realpath(const std::string &path);
1274 
1284  std::pair<bool, const char *> realpathSync(const std::string &path);
1285 
1296  void chown(const std::string &path, Uid uid, Gid gid);
1297 
1305  bool chownSync(const std::string &path, Uid uid, Gid gid);
1306 
1317  void lchown(const std::string &path, Uid uid, Gid gid);
1318 
1326  bool lchownSync(const std::string &path, Uid uid, Gid gid);
1327 
1340  void opendir(const std::string &path);
1341 
1352  bool opendirSync(const std::string &path);
1353 
1363  void closedir();
1364 
1374 
1385  void readdir();
1386 
1420  std::pair<bool, std::pair<EntryType, const char *>> readdirSync();
1421 
1422 private:
1423  uv_dirent_t dirents[1];
1424 };
1425 
1426 
1428 struct FsHelper {
1439  static OSFileDescriptor handle(FileHandle file) noexcept;
1440 
1451  static FileHandle open(OSFileDescriptor descriptor) noexcept;
1452 };
1453 
1454 
1455 }
1456 
1457 
1458 #ifndef UVW_AS_LIB
1459 #include "fs.cpp"
1460 #endif
1461 
1462 
1463 #endif // UVW_FS_INCLUDE_H
The FileReq request.
Definition: fs.h:436
std::pair< bool, std::size_t > sendfileSync(FileHandle out, int64_t offset, std::size_t length)
Sync sendfile.
void futime(Time atime, Time mtime)
Async futime.
bool truncateSync(int64_t offset)
Sync ftruncate.
void truncate(int64_t offset)
Async ftruncate.
void datasync()
Async fdatasync.
void chmod(int mode)
Async fchmod.
bool chmodSync(int mode)
Sync fchmod.
bool futimeSync(Time atime, Time mtime)
Sync futime.
std::pair< bool, std::size_t > writeSync(std::unique_ptr< char[]> buf, unsigned int len, int64_t offset)
Sync write.
std::pair< bool, std::pair< std::unique_ptr< const char[]>, std::size_t > > readSync(int64_t offset, unsigned int len)
Sync read.
void open(const std::string &path, Flags< FileOpen > flags, int mode)
Async open.
void chown(Uid uid, Gid gid)
Async fchown.
bool syncSync()
Sync fsync.
bool closeSync()
Sync close.
std::pair< bool, Stat > statSync()
Sync fstat.
void sync()
Async fsync.
bool chownSync(Uid uid, Gid gid)
Sync fchown.
void close()
Async close.
void stat()
Async fstat.
bool datasyncSync()
Sync fdatasync.
void sendfile(FileHandle out, int64_t offset, std::size_t length)
Async sendfile.
void read(int64_t offset, unsigned int len)
Async read.
void write(char *buf, unsigned int len, int64_t offset)
Async write.
void write(std::unique_ptr< char[]> buf, unsigned int len, int64_t offset)
Async write.
bool openSync(const std::string &path, Flags< FileOpen > flags, int mode)
Sync open.
Utility class to handle flags.
Definition: util.h:82
The FsReq request.
Definition: fs.h:787
bool closedirSync()
Closes synchronously a directory stream.
void readdir()
Iterates asynchronously over a directory stream one entry at a time.
void access(const std::string &path, int mode)
Async access.
void link(const std::string &old, const std::string &path)
Async link.
bool chownSync(const std::string &path, Uid uid, Gid gid)
Sync chown.
void copyfile(const std::string &old, const std::string &path, Flags< CopyFile > flags=Flags< CopyFile >{})
Copies a file asynchronously from a path to a new one.
void mkstemp(const std::string &tpl)
Async mkstemp.
bool copyfileSync(const std::string &old, const std::string &path, Flags< CopyFile > flags=Flags< CopyFile >{})
Copies a file synchronously from a path to a new one.
void statfs(const std::string &path)
Async statfs.
bool rmdirSync(const std::string &path)
Sync rmdir.
void closedir()
Closes asynchronously a directory stream.
std::pair< bool, const char * > realpathSync(const std::string &path)
Sync realpath.
bool symlinkSync(const std::string &old, const std::string &path, Flags< SymLink > flags=Flags< SymLink >{})
Sync symlink.
void chmod(const std::string &path, int mode)
Async chmod.
std::pair< bool, Statfs > statfsSync(const std::string &path)
Sync statfs.
void symlink(const std::string &old, const std::string &path, Flags< SymLink > flags=Flags< SymLink >{})
Async symlink.
std::pair< bool, std::pair< EntryType, const char * > > scandirNext()
Gets entries populated with the next directory entry data.
bool lchownSync(const std::string &path, Uid uid, Gid gid)
Sync lchown.
void readlink(const std::string &path)
Async readlink.
std::pair< bool, Stat > statSync(const std::string &path)
Sync stat.
bool lutimeSync(const std::string &path, Time atime, Time mtime)
Sync lutime.
void scandir(const std::string &path, int flags)
Async scandir.
bool utimeSync(const std::string &path, Time atime, Time mtime)
Sync utime.
void lchown(const std::string &path, Uid uid, Gid gid)
Async lchown.
void unlink(const std::string &path)
Async unlink.
void mkdtemp(const std::string &tpl)
Async mktemp.
void rename(const std::string &old, const std::string &path)
Async rename.
std::pair< bool, Stat > lstatSync(const std::string &path)
Sync lstat.
std::pair< bool, std::pair< std::string, std::size_t > > mkstempSync(const std::string &tpl)
Sync mkstemp.
void utime(const std::string &path, Time atime, Time mtime)
Async utime.
bool mkdirSync(const std::string &path, int mode)
Sync mkdir.
std::pair< bool, const char * > mkdtempSync(const std::string &tpl)
Sync mktemp.
void chown(const std::string &path, Uid uid, Gid gid)
Async chown.
void stat(const std::string &path)
Async stat.
void lutime(const std::string &path, Time atime, Time mtime)
Async lutime.
void opendir(const std::string &path)
Opens a path asynchronously as a directory stream.
bool renameSync(const std::string &old, const std::string &path)
Sync rename.
bool linkSync(const std::string &old, const std::string &path)
Sync link.
std::pair< bool, std::size_t > scandirSync(const std::string &path, int flags)
Sync scandir.
void lstat(const std::string &path)
Async lstat.
bool opendirSync(const std::string &path)
Opens a path synchronously as a directory stream.
void mkdir(const std::string &path, int mode)
Async mkdir.
bool unlinkSync(const std::string &path)
Sync unlink.
std::pair< bool, std::pair< EntryType, const char * > > readdirSync()
Iterates synchronously over a directory stream one entry at a time.
std::pair< bool, std::pair< const char *, std::size_t > > readlinkSync(const std::string &path)
Sync readlink.
void rmdir(const std::string &path)
Async rmdir.
bool chmodSync(const std::string &path, int mode)
Sync chmod.
void realpath(const std::string &path)
Async realpath.
bool accessSync(const std::string &path, int mode)
Sync access.
Base class for FsReq and/or FileReq.
Definition: fs.h:374
Request base class.
Definition: request.hpp:21
uvw default namespace.
Definition: async.h:10
uv_uid_t Uid
Definition: util.h:201
details::UVTypeWrapper< uv_file > FileHandle
Definition: util.h:189
uv_statfs_t Statfs
Definition: util.h:200
uv_gid_t Gid
Definition: util.h:202
static constexpr std::uint32_t type() noexcept
Returns a numerical identifier for a given type.
Definition: type_info.hpp:63
uv_stat_t Stat
Definition: util.h:199
details::UVTypeWrapper< uv_os_fd_t > OSFileDescriptor
Definition: util.h:191
The ErrorEvent event.
Definition: emitter.h:25
std::unique_ptr< const char[]> data
Definition: fs.h:189
Default FsEvent event.
Definition: fs.h:169
const char * path
Definition: fs.h:172
Helper functions.
Definition: fs.h:1428
static OSFileDescriptor handle(FileHandle file) noexcept
Gets the OS dependent handle.
static FileHandle open(OSFileDescriptor descriptor) noexcept
Gets the file descriptor.