summaryrefslogtreecommitdiff
path: root/src/node_dir.h
diff options
context:
space:
mode:
authorJeremiah Senkpiel <fishrock123@rocketmail.com>2019-08-27 17:14:27 -0700
committerJeremiah Senkpiel <fishrock123@rocketmail.com>2019-10-08 10:34:48 -0700
commitcbd8d715b2286e5726e6988921f5c870cbf74127 (patch)
tree20c878fd9d7882f2a5b43718a0b3daad4a9a0255 /src/node_dir.h
parent064e111515185529b6f943dc66929440557fd609 (diff)
downloadandroid-node-v8-cbd8d715b2286e5726e6988921f5c870cbf74127.tar.gz
android-node-v8-cbd8d715b2286e5726e6988921f5c870cbf74127.tar.bz2
android-node-v8-cbd8d715b2286e5726e6988921f5c870cbf74127.zip
fs: introduce `opendir()` and `fs.Dir`
This adds long-requested methods for asynchronously interacting and iterating through directory entries by using `uv_fs_opendir`, `uv_fs_readdir`, and `uv_fs_closedir`. `fs.opendir()` and friends return an `fs.Dir`, which contains methods for doing reads and cleanup. `fs.Dir` also has the async iterator symbol exposed. The `read()` method and friends only return `fs.Dirent`s for this API. Having a entry type or doing a `stat` call is deemed to be necessary in the majority of cases, so just returning dirents seems like the logical choice for a new api. Reading when there are no more entries returns `null` instead of a dirent. However the async iterator hides that (and does automatic cleanup). The code lives in separate files from the rest of fs, this is done partially to prevent over-pollution of those (already very large) files, but also in the case of js allows loading into `fsPromises`. Due to async_hooks, this introduces a new handle type of `DIRHANDLE`. This PR does not attempt to make complete optimization of this feature. Notable future improvements include: - Moving promise work into C++ land like FileHandle. - Possibly adding `readv()` to do multi-entry directory reads. - Aliasing `fs.readdir` to `fs.scandir` and doing a deprecation. Refs: https://github.com/nodejs/node-v0.x-archive/issues/388 Refs: https://github.com/nodejs/node/issues/583 Refs: https://github.com/libuv/libuv/pull/2057 PR-URL: https://github.com/nodejs/node/pull/29349 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: David Carlier <devnexen@gmail.com>
Diffstat (limited to 'src/node_dir.h')
-rw-r--r--src/node_dir.h60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/node_dir.h b/src/node_dir.h
new file mode 100644
index 0000000000..e099fe5510
--- /dev/null
+++ b/src/node_dir.h
@@ -0,0 +1,60 @@
+#ifndef SRC_NODE_DIR_H_
+#define SRC_NODE_DIR_H_
+
+#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
+
+#include "node_file.h"
+#include "node.h"
+#include "req_wrap-inl.h"
+
+namespace node {
+
+namespace fs_dir {
+
+// Needed to propagate `uv_dir_t`.
+class DirHandle : public AsyncWrap {
+ public:
+ static constexpr int kDirHandleFieldCount = 1;
+
+ static DirHandle* New(Environment* env, uv_dir_t* dir);
+ ~DirHandle() override;
+
+ static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void Open(const v8::FunctionCallbackInfo<Value>& args);
+ static void Read(const v8::FunctionCallbackInfo<Value>& args);
+ static void Close(const v8::FunctionCallbackInfo<Value>& args);
+
+ inline uv_dir_t* dir() { return dir_; }
+ AsyncWrap* GetAsyncWrap() { return this; }
+
+ void MemoryInfo(MemoryTracker* tracker) const override {
+ tracker->TrackFieldWithSize("dir", sizeof(*dir_));
+ }
+
+ SET_MEMORY_INFO_NAME(DirHandle)
+ SET_SELF_SIZE(DirHandle)
+
+ DirHandle(const DirHandle&) = delete;
+ DirHandle& operator=(const DirHandle&) = delete;
+ DirHandle(const DirHandle&&) = delete;
+ DirHandle& operator=(const DirHandle&&) = delete;
+
+ private:
+ DirHandle(Environment* env, v8::Local<v8::Object> obj, uv_dir_t* dir);
+
+ // Synchronous close that emits a warning
+ void GCClose();
+
+ uv_dir_t* dir_;
+ uv_dirent_t dirent_;
+ bool closing_ = false;
+ bool closed_ = false;
+};
+
+} // namespace fs_dir
+
+} // namespace node
+
+#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
+
+#endif // SRC_NODE_DIR_H_