GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_file.h Lines: 35 43 81.4 %
Date: 2020-02-19 22:14:06 Branches: 2 2 100.0 %

Line Branch Exec Source
1
#ifndef SRC_NODE_FILE_H_
2
#define SRC_NODE_FILE_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "node.h"
7
#include "aliased_buffer.h"
8
#include "stream_base.h"
9
#include <iostream>
10
11
namespace node {
12
namespace fs {
13
14
// structure used to store state during a complex operation, e.g., mkdirp.
15
8910
class FSContinuationData : public MemoryRetainer {
16
 public:
17
  inline FSContinuationData(uv_fs_t* req, int mode, uv_fs_cb done_cb);
18
19
  inline void PushPath(std::string&& path);
20
  inline void PushPath(const std::string& path);
21
  inline std::string PopPath();
22
  // Used by mkdirp to track the first path created:
23
  inline void MaybeSetFirstPath(const std::string& path);
24
  inline void Done(int result);
25
26
10
  int mode() const { return mode_; }
27
8953
  const std::vector<std::string>& paths() const { return paths_; }
28
221
  const std::string& first_path() const { return first_path_; }
29
30
  void MemoryInfo(MemoryTracker* tracker) const override;
31
  SET_MEMORY_INFO_NAME(FSContinuationData)
32
  SET_SELF_SIZE(FSContinuationData)
33
34
 private:
35
  uv_fs_cb done_cb_;
36
  uv_fs_t* req_;
37
  int mode_;
38
  std::vector<std::string> paths_;
39
  std::string first_path_;
40
};
41
42
class FSReqBase : public ReqWrap<uv_fs_t> {
43
 public:
44
  typedef MaybeStackBuffer<char, 64> FSReqBuffer;
45
46
  inline FSReqBase(Environment* env,
47
                   v8::Local<v8::Object> req,
48
                   AsyncWrap::ProviderType type,
49
                   bool use_bigint);
50
  ~FSReqBase() override;
51
52
  inline void Init(const char* syscall,
53
                   const char* data,
54
                   size_t len,
55
                   enum encoding encoding);
56
  inline FSReqBuffer& Init(const char* syscall, size_t len,
57
                           enum encoding encoding);
58
59
  virtual void Reject(v8::Local<v8::Value> reject) = 0;
60
  virtual void Resolve(v8::Local<v8::Value> value) = 0;
61
  virtual void ResolveStat(const uv_stat_t* stat) = 0;
62
  virtual void SetReturnValue(
63
      const v8::FunctionCallbackInfo<v8::Value>& args) = 0;
64
65
3980
  const char* syscall() const { return syscall_; }
66
3980
  const char* data() const { return has_data_ ? *buffer_ : nullptr; }
67
6427
  enum encoding encoding() const { return encoding_; }
68
3852
  bool use_bigint() const { return use_bigint_; }
69
70
140
  FSContinuationData* continuation_data() const {
71
140
    return continuation_data_.get();
72
  }
73
14
  void set_continuation_data(std::unique_ptr<FSContinuationData> data) {
74
14
    continuation_data_ = std::move(data);
75
14
  }
76
77
49723
  static FSReqBase* from_req(uv_fs_t* req) {
78
49723
    return static_cast<FSReqBase*>(ReqWrap::from_req(req));
79
  }
80
81
  FSReqBase(const FSReqBase&) = delete;
82
  FSReqBase& operator=(const FSReqBase&) = delete;
83
84
  void MemoryInfo(MemoryTracker* tracker) const override;
85
86
 private:
87
  std::unique_ptr<FSContinuationData> continuation_data_;
88
  enum encoding encoding_ = UTF8;
89
  bool has_data_ = false;
90
  const char* syscall_ = nullptr;
91
  bool use_bigint_ = false;
92
93
  // Typically, the content of buffer_ is something like a file name, so
94
  // something around 64 bytes should be enough.
95
  FSReqBuffer buffer_;
96
};
97
98
96880
class FSReqCallback final : public FSReqBase {
99
 public:
100
  inline FSReqCallback(Environment* env,
101
                       v8::Local<v8::Object> req,
102
                       bool use_bigint);
103
104
  void Reject(v8::Local<v8::Value> reject) override;
105
  void Resolve(v8::Local<v8::Value> value) override;
106
  void ResolveStat(const uv_stat_t* stat) override;
107
  void SetReturnValue(const v8::FunctionCallbackInfo<v8::Value>& args) override;
108
109
1
  SET_MEMORY_INFO_NAME(FSReqCallback)
110
1
  SET_SELF_SIZE(FSReqCallback)
111
112
  FSReqCallback(const FSReqCallback&) = delete;
113
  FSReqCallback& operator=(const FSReqCallback&) = delete;
114
};
115
116
template <typename NativeT, typename V8T>
117
void FillStatsArray(AliasedBufferBase<NativeT, V8T>* fields,
118
                    const uv_stat_t* s,
119
                    const size_t offset = 0);
120
121
inline v8::Local<v8::Value> FillGlobalStatsArray(Environment* env,
122
                                                 const bool use_bigint,
123
                                                 const uv_stat_t* s,
124
                                                 const bool second = false);
125
126
template <typename AliasedBufferT>
127
class FSReqPromise final : public FSReqBase {
128
 public:
129
  static inline FSReqPromise* New(Environment* env, bool use_bigint);
130
  inline ~FSReqPromise() override;
131
132
  inline void Reject(v8::Local<v8::Value> reject) override;
133
  inline void Resolve(v8::Local<v8::Value> value) override;
134
  inline void ResolveStat(const uv_stat_t* stat) override;
135
  inline void SetReturnValue(
136
      const v8::FunctionCallbackInfo<v8::Value>& args) override;
137
  inline void MemoryInfo(MemoryTracker* tracker) const override;
138
139
1
  SET_MEMORY_INFO_NAME(FSReqPromise)
140
1
  SET_SELF_SIZE(FSReqPromise)
141
142
  FSReqPromise(const FSReqPromise&) = delete;
143
  FSReqPromise& operator=(const FSReqPromise&) = delete;
144
  FSReqPromise(const FSReqPromise&&) = delete;
145
  FSReqPromise& operator=(const FSReqPromise&&) = delete;
146
147
 private:
148
  inline FSReqPromise(Environment* env,
149
                      v8::Local<v8::Object> obj,
150
                      bool use_bigint);
151
152
  bool finished_ = false;
153
  AliasedBufferT stats_field_array_;
154
};
155
156
class FSReqAfterScope final {
157
 public:
158
  FSReqAfterScope(FSReqBase* wrap, uv_fs_t* req);
159
  ~FSReqAfterScope();
160
161
  bool Proceed();
162
163
  void Reject(uv_fs_t* req);
164
165
  FSReqAfterScope(const FSReqAfterScope&) = delete;
166
  FSReqAfterScope& operator=(const FSReqAfterScope&) = delete;
167
  FSReqAfterScope(const FSReqAfterScope&&) = delete;
168
  FSReqAfterScope& operator=(const FSReqAfterScope&&) = delete;
169
170
 private:
171
  FSReqBase* wrap_ = nullptr;
172
  uv_fs_t* req_ = nullptr;
173
  v8::HandleScope handle_scope_;
174
  v8::Context::Scope context_scope_;
175
};
176
177
class FileHandle;
178
179
// A request wrap specifically for uv_fs_read()s scheduled for reading
180
// from a FileHandle.
181
class FileHandleReadWrap final : public ReqWrap<uv_fs_t> {
182
 public:
183
  FileHandleReadWrap(FileHandle* handle, v8::Local<v8::Object> obj);
184
  ~FileHandleReadWrap() override;
185
186
212
  static inline FileHandleReadWrap* from_req(uv_fs_t* req) {
187
212
    return static_cast<FileHandleReadWrap*>(ReqWrap::from_req(req));
188
  }
189
190
  void MemoryInfo(MemoryTracker* tracker) const override;
191
  SET_MEMORY_INFO_NAME(FileHandleReadWrap)
192
  SET_SELF_SIZE(FileHandleReadWrap)
193
194
 private:
195
  FileHandle* file_handle_;
196
  uv_buf_t buffer_;
197
198
  friend class FileHandle;
199
};
200
201
// A wrapper for a file descriptor that will automatically close the fd when
202
// the object is garbage collected
203
class FileHandle final : public AsyncWrap, public StreamBase {
204
 public:
205
  static FileHandle* New(Environment* env,
206
                         int fd,
207
                         v8::Local<v8::Object> obj = v8::Local<v8::Object>());
208
  ~FileHandle() override;
209
210
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
211
212
270
  int GetFD() override { return fd_; }
213
214
  // Will asynchronously close the FD and return a Promise that will
215
  // be resolved once closing is complete.
216
  static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
217
218
  // Releases ownership of the FD.
219
  static void ReleaseFD(const v8::FunctionCallbackInfo<v8::Value>& args);
220
221
  // StreamBase interface:
222
  int ReadStart() override;
223
  int ReadStop() override;
224
225
487
  bool IsAlive() override { return !closed_; }
226
217
  bool IsClosing() override { return closing_; }
227
324
  AsyncWrap* GetAsyncWrap() override { return this; }
228
229
  // In the case of file streams, shutting down corresponds to closing.
230
  ShutdownWrap* CreateShutdownWrap(v8::Local<v8::Object> object) override;
231
  int DoShutdown(ShutdownWrap* req_wrap) override;
232
233
  int DoWrite(WriteWrap* w,
234
              uv_buf_t* bufs,
235
              size_t count,
236
              uv_stream_t* send_handle) override;
237
238
  void MemoryInfo(MemoryTracker* tracker) const override;
239
240
  SET_MEMORY_INFO_NAME(FileHandle)
241
  SET_SELF_SIZE(FileHandle)
242
243
  FileHandle(const FileHandle&) = delete;
244
  FileHandle& operator=(const FileHandle&) = delete;
245
  FileHandle(const FileHandle&&) = delete;
246
  FileHandle& operator=(const FileHandle&&) = delete;
247
248
 private:
249
  FileHandle(Environment* env, v8::Local<v8::Object> obj, int fd);
250
251
  // Synchronous close that emits a warning
252
  void Close();
253
  void AfterClose();
254
255
  class CloseReq final : public ReqWrap<uv_fs_t> {
256
   public:
257
    CloseReq(Environment* env,
258
             v8::Local<v8::Object> obj,
259
             v8::Local<v8::Promise> promise,
260
             v8::Local<v8::Value> ref);
261
    ~CloseReq() override;
262
263
    FileHandle* file_handle();
264
265
    void MemoryInfo(MemoryTracker* tracker) const override;
266
267
    SET_MEMORY_INFO_NAME(CloseReq)
268
    SET_SELF_SIZE(CloseReq)
269
270
    void Resolve();
271
272
    void Reject(v8::Local<v8::Value> reason);
273
274
269
    static CloseReq* from_req(uv_fs_t* req) {
275
269
      return static_cast<CloseReq*>(ReqWrap::from_req(req));
276
    }
277
278
    CloseReq(const CloseReq&) = delete;
279
    CloseReq& operator=(const CloseReq&) = delete;
280
    CloseReq(const CloseReq&&) = delete;
281
    CloseReq& operator=(const CloseReq&&) = delete;
282
283
   private:
284
    v8::Global<v8::Promise> promise_{};
285
    v8::Global<v8::Value> ref_{};
286
  };
287
288
  // Asynchronous close
289
  v8::MaybeLocal<v8::Promise> ClosePromise();
290
291
  int fd_;
292
  bool closing_ = false;
293
  bool closed_ = false;
294
  int64_t read_offset_ = -1;
295
  int64_t read_length_ = -1;
296
297
  bool reading_ = false;
298
  std::unique_ptr<FileHandleReadWrap> current_read_ = nullptr;
299
};
300
301
int MKDirpSync(uv_loop_t* loop,
302
               uv_fs_t* req,
303
               const std::string& path,
304
               int mode,
305
               uv_fs_cb cb = nullptr);
306
307
class FSReqWrapSync {
308
 public:
309
313632
  FSReqWrapSync() = default;
310
313632
  ~FSReqWrapSync() { uv_fs_req_cleanup(&req); }
311
  uv_fs_t req;
312
313
22678
  FSContinuationData* continuation_data() const {
314
22678
    return continuation_data_.get();
315
  }
316
4441
  void set_continuation_data(std::unique_ptr<FSContinuationData> data) {
317
4441
    continuation_data_ = std::move(data);
318
4441
  }
319
320
  FSReqWrapSync(const FSReqWrapSync&) = delete;
321
  FSReqWrapSync& operator=(const FSReqWrapSync&) = delete;
322
323
 private:
324
  std::unique_ptr<FSContinuationData> continuation_data_;
325
};
326
327
// TODO(addaleax): Currently, callers check the return value and assume
328
// that nullptr indicates a synchronous call, rather than a failure.
329
// Failure conditions should be disambiguated and handled appropriately.
330
inline FSReqBase* GetReqWrap(Environment* env, v8::Local<v8::Value> value,
331
                             bool use_bigint = false);
332
333
// Returns nullptr if the operation fails from the start.
334
template <typename Func, typename... Args>
335
inline FSReqBase* AsyncDestCall(Environment* env, FSReqBase* req_wrap,
336
                                const v8::FunctionCallbackInfo<v8::Value>& args,
337
                                const char* syscall, const char* dest,
338
                                size_t len, enum encoding enc, uv_fs_cb after,
339
                                Func fn, Args... fn_args);
340
341
// Returns nullptr if the operation fails from the start.
342
template <typename Func, typename... Args>
343
inline FSReqBase* AsyncCall(Environment* env,
344
                            FSReqBase* req_wrap,
345
                            const v8::FunctionCallbackInfo<v8::Value>& args,
346
                            const char* syscall, enum encoding enc,
347
                            uv_fs_cb after, Func fn, Args... fn_args);
348
349
// Template counterpart of SYNC_CALL, except that it only puts
350
// the error number and the syscall in the context instead of
351
// creating an error in the C++ land.
352
// ctx must be checked using value->IsObject() before being passed.
353
template <typename Func, typename... Args>
354
inline int SyncCall(Environment* env, v8::Local<v8::Value> ctx,
355
                    FSReqWrapSync* req_wrap, const char* syscall,
356
                    Func fn, Args... args);
357
358
}  // namespace fs
359
360
}  // namespace node
361
362
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
363
364
#endif  // SRC_NODE_FILE_H_