GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_process_methods.cc Lines: 282 297 94.9 %
Date: 2022-08-29 04:21:03 Branches: 73 112 65.2 %

Line Branch Exec Source
1
#include "async_wrap-inl.h"
2
#include "base_object-inl.h"
3
#include "debug_utils-inl.h"
4
#include "env-inl.h"
5
#include "memory_tracker-inl.h"
6
#include "node.h"
7
#include "node_errors.h"
8
#include "node_external_reference.h"
9
#include "node_internals.h"
10
#include "node_process-inl.h"
11
#include "util-inl.h"
12
#include "uv.h"
13
#include "v8-fast-api-calls.h"
14
#include "v8.h"
15
16
#include <vector>
17
18
#if HAVE_INSPECTOR
19
#include "inspector_io.h"
20
#endif
21
22
#include <climits>  // PATH_MAX
23
#include <cstdio>
24
25
#if defined(_MSC_VER)
26
#include <direct.h>
27
#include <io.h>
28
#define umask _umask
29
typedef int mode_t;
30
#else
31
#include <pthread.h>
32
#include <sys/resource.h>  // getrlimit, setrlimit
33
#include <termios.h>  // tcgetattr, tcsetattr
34
#endif
35
36
namespace node {
37
38
using v8::Array;
39
using v8::ArrayBuffer;
40
using v8::CFunction;
41
using v8::Context;
42
using v8::Float64Array;
43
using v8::FunctionCallbackInfo;
44
using v8::HeapStatistics;
45
using v8::Integer;
46
using v8::Isolate;
47
using v8::Local;
48
using v8::NewStringType;
49
using v8::Number;
50
using v8::Object;
51
using v8::String;
52
using v8::Uint32;
53
using v8::Value;
54
55
namespace per_process {
56
Mutex umask_mutex;
57
}   // namespace per_process
58
59
// Microseconds in a second, as a float, used in CPUUsage() below
60
#define MICROS_PER_SEC 1e6
61
// used in Hrtime() and Uptime() below
62
#define NANOS_PER_SEC 1000000000
63
64
static void Abort(const FunctionCallbackInfo<Value>& args) {
65
  Abort();
66
}
67
68
// For internal testing only, not exposed to userland.
69
static void CauseSegfault(const FunctionCallbackInfo<Value>& args) {
70
  // This should crash hard all platforms.
71
  volatile void** d = static_cast<volatile void**>(nullptr);
72
  *d = nullptr;
73
}
74
75
498
static void Chdir(const FunctionCallbackInfo<Value>& args) {
76
498
  Environment* env = Environment::GetCurrent(args);
77
498
  CHECK(env->owns_process_state());
78
79
498
  CHECK_EQ(args.Length(), 1);
80
996
  CHECK(args[0]->IsString());
81
498
  Utf8Value path(env->isolate(), args[0]);
82
498
  int err = uv_chdir(*path);
83
498
  if (err) {
84
    // Also include the original working directory, since that will usually
85
    // be helpful information when debugging a `chdir()` failure.
86
    char buf[PATH_MAX_BYTES];
87
1
    size_t cwd_len = sizeof(buf);
88
1
    uv_cwd(buf, &cwd_len);
89
1
    return env->ThrowUVException(err, "chdir", nullptr, buf, *path);
90
  }
91
}
92
93
556
inline Local<ArrayBuffer> get_fields_array_buffer(
94
    const FunctionCallbackInfo<Value>& args,
95
    size_t index,
96
    size_t array_length) {
97

1112
  CHECK(args[index]->IsFloat64Array());
98
1668
  Local<Float64Array> arr = args[index].As<Float64Array>();
99
556
  CHECK_EQ(arr->Length(), array_length);
100
556
  return arr->Buffer();
101
}
102
103
// CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
104
// to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
105
// which are uv_timeval_t structs (long tv_sec, long tv_usec).
106
// Returns those values as Float64 microseconds in the elements of the array
107
// passed to the function.
108
33
static void CPUUsage(const FunctionCallbackInfo<Value>& args) {
109
33
  Environment* env = Environment::GetCurrent(args);
110
  uv_rusage_t rusage;
111
112
  // Call libuv to get the values we'll return.
113
33
  int err = uv_getrusage(&rusage);
114
33
  if (err)
115
    return env->ThrowUVException(err, "uv_getrusage");
116
117
  // Get the double array pointer from the Float64Array argument.
118
33
  Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 2);
119
33
  double* fields = static_cast<double*>(ab->Data());
120
121
  // Set the Float64Array elements to be user / system values in microseconds.
122
33
  fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
123
33
  fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
124
}
125
126
7012
static void Cwd(const FunctionCallbackInfo<Value>& args) {
127
7012
  Environment* env = Environment::GetCurrent(args);
128
7012
  CHECK(env->has_run_bootstrapping_code());
129
  char buf[PATH_MAX_BYTES];
130
7012
  size_t cwd_len = sizeof(buf);
131
7012
  int err = uv_cwd(buf, &cwd_len);
132
7012
  if (err)
133
13
    return env->ThrowUVException(err, "uv_cwd");
134
135
6999
  Local<String> cwd = String::NewFromUtf8(env->isolate(),
136
                                          buf,
137
                                          NewStringType::kNormal,
138
13998
                                          cwd_len).ToLocalChecked();
139
13998
  args.GetReturnValue().Set(cwd);
140
}
141
142
65
static void Kill(const FunctionCallbackInfo<Value>& args) {
143
65
  Environment* env = Environment::GetCurrent(args);
144
65
  Local<Context> context = env->context();
145
146
65
  if (args.Length() < 2) {
147
    THROW_ERR_MISSING_ARGS(env, "Bad argument.");
148
  }
149
150
  int pid;
151
130
  if (!args[0]->Int32Value(context).To(&pid)) return;
152
  int sig;
153
130
  if (!args[1]->Int32Value(context).To(&sig)) return;
154
155
65
  uv_pid_t own_pid = uv_os_getpid();
156
193
  if (sig > 0 &&
157



93
      (pid == 0 || pid == -1 || pid == own_pid || pid == -own_pid) &&
158
28
      !HasSignalJSHandler(sig)) {
159
    // This is most likely going to terminate this process.
160
    // It's not an exact method but it might be close enough.
161
19
    RunAtExit(env);
162
  }
163
164
65
  int err = uv_kill(pid, sig);
165
130
  args.GetReturnValue().Set(err);
166
}
167
168
6
static void Rss(const FunctionCallbackInfo<Value>& args) {
169
6
  Environment* env = Environment::GetCurrent(args);
170
171
  size_t rss;
172
6
  int err = uv_resident_set_memory(&rss);
173
6
  if (err)
174
    return env->ThrowUVException(err, "uv_resident_set_memory");
175
176
12
  args.GetReturnValue().Set(static_cast<double>(rss));
177
}
178
179
522
static void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
180
522
  Environment* env = Environment::GetCurrent(args);
181
182
522
  Isolate* isolate = env->isolate();
183
  // V8 memory usage
184
522
  HeapStatistics v8_heap_stats;
185
522
  isolate->GetHeapStatistics(&v8_heap_stats);
186
187
  NodeArrayBufferAllocator* array_buffer_allocator =
188
522
      env->isolate_data()->node_allocator();
189
190
  // Get the double array pointer from the Float64Array argument.
191
522
  Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 5);
192
522
  double* fields = static_cast<double*>(ab->Data());
193
194
  size_t rss;
195
522
  int err = uv_resident_set_memory(&rss);
196
522
  if (err)
197
    return env->ThrowUVException(err, "uv_resident_set_memory");
198
199
522
  fields[0] = static_cast<double>(rss);
200
522
  fields[1] = static_cast<double>(v8_heap_stats.total_heap_size());
201
522
  fields[2] = static_cast<double>(v8_heap_stats.used_heap_size());
202
522
  fields[3] = static_cast<double>(v8_heap_stats.external_memory());
203
522
  fields[4] =
204
      array_buffer_allocator == nullptr
205
1044
          ? 0
206
522
          : static_cast<double>(array_buffer_allocator->total_mem_usage());
207
}
208
209
22
void RawDebug(const FunctionCallbackInfo<Value>& args) {
210


66
  CHECK(args.Length() == 1 && args[0]->IsString() &&
211
        "must be called with a single string");
212
44
  Utf8Value message(args.GetIsolate(), args[0]);
213
22
  FPrintF(stderr, "%s\n", message);
214
22
  fflush(stderr);
215
22
}
216
217
4377
static void Umask(const FunctionCallbackInfo<Value>& args) {
218
4377
  Environment* env = Environment::GetCurrent(args);
219
4377
  CHECK(env->has_run_bootstrapping_code());
220
4377
  CHECK_EQ(args.Length(), 1);
221

13124
  CHECK(args[0]->IsUndefined() || args[0]->IsUint32());
222
4377
  Mutex::ScopedLock scoped_lock(per_process::umask_mutex);
223
224
  uint32_t old;
225
8754
  if (args[0]->IsUndefined()) {
226
7
    old = umask(0);
227
7
    umask(static_cast<mode_t>(old));
228
  } else {
229
8740
    int oct = args[0].As<Uint32>()->Value();
230
4370
    old = umask(static_cast<mode_t>(oct));
231
  }
232
233
8754
  args.GetReturnValue().Set(old);
234
4377
}
235
236
4
static void Uptime(const FunctionCallbackInfo<Value>& args) {
237
4
  Environment* env = Environment::GetCurrent(args);
238
239
4
  uv_update_time(env->event_loop());
240
  double uptime =
241
4
      static_cast<double>(uv_hrtime() - per_process::node_start_time);
242
4
  Local<Number> result = Number::New(env->isolate(), uptime / NANOS_PER_SEC);
243
4
  args.GetReturnValue().Set(result);
244
4
}
245
246
1
static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
247
1
  Environment* env = Environment::GetCurrent(args);
248
249
1
  std::vector<Local<Value>> request_v;
250
13
  for (ReqWrapBase* req_wrap : *env->req_wrap_queue()) {
251
12
    AsyncWrap* w = req_wrap->GetAsyncWrap();
252
12
    if (w->persistent().IsEmpty())
253
      continue;
254
12
    request_v.emplace_back(w->GetOwner());
255
  }
256
257
2
  args.GetReturnValue().Set(
258
      Array::New(env->isolate(), request_v.data(), request_v.size()));
259
1
}
260
261
28
static void GetActiveRequestsInfo(const FunctionCallbackInfo<Value>& args) {
262
28
  Environment* env = Environment::GetCurrent(args);
263
264
28
  std::vector<Local<Value>> requests_info;
265
50
  for (ReqWrapBase* req_wrap : *env->req_wrap_queue()) {
266
22
    AsyncWrap* w = req_wrap->GetAsyncWrap();
267
22
    if (w->persistent().IsEmpty()) continue;
268
22
    requests_info.emplace_back(OneByteString(env->isolate(),
269
22
                               w->MemoryInfoName().c_str()));
270
  }
271
272
56
  args.GetReturnValue().Set(
273
      Array::New(env->isolate(), requests_info.data(), requests_info.size()));
274
28
}
275
276
// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
277
// implemented here for consistency with GetActiveRequests().
278
4
void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
279
4
  Environment* env = Environment::GetCurrent(args);
280
281
4
  std::vector<Local<Value>> handle_v;
282
24
  for (auto w : *env->handle_wrap_queue()) {
283
20
    if (!HandleWrap::HasRef(w))
284
1
      continue;
285
19
    handle_v.emplace_back(w->GetOwner());
286
  }
287
8
  args.GetReturnValue().Set(
288
      Array::New(env->isolate(), handle_v.data(), handle_v.size()));
289
4
}
290
291
28
void GetActiveHandlesInfo(const FunctionCallbackInfo<Value>& args) {
292
28
  Environment* env = Environment::GetCurrent(args);
293
294
28
  std::vector<Local<Value>> handles_info;
295
126
  for (HandleWrap* w : *env->handle_wrap_queue()) {
296

98
    if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w)) continue;
297
98
    handles_info.emplace_back(OneByteString(env->isolate(),
298
98
                              w->MemoryInfoName().c_str()));
299
  }
300
301
56
  args.GetReturnValue().Set(
302
      Array::New(env->isolate(), handles_info.data(), handles_info.size()));
303
28
}
304
305
1
static void ResourceUsage(const FunctionCallbackInfo<Value>& args) {
306
1
  Environment* env = Environment::GetCurrent(args);
307
308
  uv_rusage_t rusage;
309
1
  int err = uv_getrusage(&rusage);
310
1
  if (err)
311
    return env->ThrowUVException(err, "uv_getrusage");
312
313
1
  Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 16);
314
1
  double* fields = static_cast<double*>(ab->Data());
315
316
1
  fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
317
1
  fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
318
1
  fields[2] = static_cast<double>(rusage.ru_maxrss);
319
1
  fields[3] = static_cast<double>(rusage.ru_ixrss);
320
1
  fields[4] = static_cast<double>(rusage.ru_idrss);
321
1
  fields[5] = static_cast<double>(rusage.ru_isrss);
322
1
  fields[6] = static_cast<double>(rusage.ru_minflt);
323
1
  fields[7] = static_cast<double>(rusage.ru_majflt);
324
1
  fields[8] = static_cast<double>(rusage.ru_nswap);
325
1
  fields[9] = static_cast<double>(rusage.ru_inblock);
326
1
  fields[10] = static_cast<double>(rusage.ru_oublock);
327
1
  fields[11] = static_cast<double>(rusage.ru_msgsnd);
328
1
  fields[12] = static_cast<double>(rusage.ru_msgrcv);
329
1
  fields[13] = static_cast<double>(rusage.ru_nsignals);
330
1
  fields[14] = static_cast<double>(rusage.ru_nvcsw);
331
1
  fields[15] = static_cast<double>(rusage.ru_nivcsw);
332
}
333
334
#ifdef __POSIX__
335
4
static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
336
4
  Environment* env = Environment::GetCurrent(args);
337
338
4
  if (args.Length() < 1) {
339
    return THROW_ERR_MISSING_ARGS(env, "Invalid number of arguments.");
340
  }
341
342
4
  CHECK(args[0]->IsNumber());
343
8
  pid_t pid = args[0].As<Integer>()->Value();
344
4
  int r = kill(pid, SIGUSR1);
345
346
4
  if (r != 0) {
347
1
    return env->ThrowErrnoException(errno, "kill");
348
  }
349
}
350
#endif  // __POSIX__
351
352
#ifdef _WIN32
353
static int GetDebugSignalHandlerMappingName(DWORD pid,
354
                                            wchar_t* buf,
355
                                            size_t buf_len) {
356
  return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
357
}
358
359
static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
360
  Environment* env = Environment::GetCurrent(args);
361
  Isolate* isolate = args.GetIsolate();
362
363
  if (args.Length() < 1) {
364
    return THROW_ERR_MISSING_ARGS(env, "Invalid number of arguments.");
365
  }
366
367
  HANDLE process = nullptr;
368
  HANDLE thread = nullptr;
369
  HANDLE mapping = nullptr;
370
  wchar_t mapping_name[32];
371
  LPTHREAD_START_ROUTINE* handler = nullptr;
372
  DWORD pid = 0;
373
374
  auto cleanup = OnScopeLeave([&]() {
375
    if (process != nullptr) CloseHandle(process);
376
    if (thread != nullptr) CloseHandle(thread);
377
    if (handler != nullptr) UnmapViewOfFile(handler);
378
    if (mapping != nullptr) CloseHandle(mapping);
379
  });
380
381
  CHECK(args[0]->IsNumber());
382
  pid = static_cast<DWORD>(args[0].As<Integer>()->Value());
383
384
  process =
385
      OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
386
                      PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
387
                  FALSE,
388
                  pid);
389
  if (process == nullptr) {
390
    isolate->ThrowException(
391
        WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
392
    return;
393
  }
394
395
  if (GetDebugSignalHandlerMappingName(
396
          pid, mapping_name, arraysize(mapping_name)) < 0) {
397
    env->ThrowErrnoException(errno, "sprintf");
398
    return;
399
  }
400
401
  mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
402
  if (mapping == nullptr) {
403
    isolate->ThrowException(
404
        WinapiErrnoException(isolate, GetLastError(), "OpenFileMappingW"));
405
    return;
406
  }
407
408
  handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
409
      MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, sizeof *handler));
410
  if (handler == nullptr || *handler == nullptr) {
411
    isolate->ThrowException(
412
        WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
413
    return;
414
  }
415
416
  thread =
417
      CreateRemoteThread(process, nullptr, 0, *handler, nullptr, 0, nullptr);
418
  if (thread == nullptr) {
419
    isolate->ThrowException(
420
        WinapiErrnoException(isolate, GetLastError(), "CreateRemoteThread"));
421
    return;
422
  }
423
424
  // Wait for the thread to terminate
425
  if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
426
    isolate->ThrowException(
427
        WinapiErrnoException(isolate, GetLastError(), "WaitForSingleObject"));
428
    return;
429
  }
430
}
431
#endif  // _WIN32
432
433
5
static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
434
#if HAVE_INSPECTOR
435
5
  Environment* env = Environment::GetCurrent(args);
436
5
  if (env->inspector_agent()->IsListening()) {
437
4
    env->inspector_agent()->Stop();
438
  }
439
#endif
440
5
}
441
442
434
static void ReallyExit(const FunctionCallbackInfo<Value>& args) {
443
434
  Environment* env = Environment::GetCurrent(args);
444
434
  RunAtExit(env);
445
434
  int code = args[0]->Int32Value(env->context()).FromMaybe(0);
446
434
  env->Exit(code);
447
61
}
448
449
namespace process {
450
451
6189
BindingData::BindingData(Environment* env, v8::Local<v8::Object> object)
452
6189
    : SnapshotableObject(env, object, type_int) {
453
6189
  Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), kBufferSize);
454
6189
  array_buffer_.Reset(env->isolate(), ab);
455
  object
456
6189
      ->Set(env->context(),
457
            FIXED_ONE_BYTE_STRING(env->isolate(), "hrtimeBuffer"),
458
18567
            ab)
459
      .ToChecked();
460
6189
  backing_store_ = ab->GetBackingStore();
461
6189
}
462
463
v8::CFunction BindingData::fast_number_(v8::CFunction::Make(FastNumber));
464
v8::CFunction BindingData::fast_bigint_(v8::CFunction::Make(FastBigInt));
465
466
781
void BindingData::AddMethods() {
467
781
  Local<Context> ctx = env()->context();
468
781
  SetFastMethod(ctx, object(), "hrtime", SlowNumber, &fast_number_);
469
781
  SetFastMethod(ctx, object(), "hrtimeBigInt", SlowBigInt, &fast_bigint_);
470
781
}
471
472
5415
void BindingData::RegisterExternalReferences(
473
    ExternalReferenceRegistry* registry) {
474
5415
  registry->Register(SlowNumber);
475
5415
  registry->Register(SlowBigInt);
476
5415
  registry->Register(FastNumber);
477
5415
  registry->Register(FastBigInt);
478
5415
  registry->Register(fast_number_.GetTypeInfo());
479
5415
  registry->Register(fast_bigint_.GetTypeInfo());
480
5415
}
481
482
BindingData* BindingData::FromV8Value(Local<Value> value) {
483
  Local<Object> v8_object = value.As<Object>();
484
  return static_cast<BindingData*>(
485
      v8_object->GetAlignedPointerFromInternalField(BaseObject::kSlot));
486
}
487
488
24
void BindingData::MemoryInfo(MemoryTracker* tracker) const {
489
24
  tracker->TrackField("array_buffer", array_buffer_);
490
24
}
491
492
// This is the legacy version of hrtime before BigInt was introduced in
493
// JavaScript.
494
// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
495
// so this function instead fills in an Uint32Array with 3 entries,
496
// to avoid any integer overflow possibility.
497
// The first two entries contain the second part of the value
498
// broken into the upper/lower 32 bits to be converted back in JS,
499
// because there is no Uint64Array in JS.
500
// The third entry contains the remaining nanosecond part of the value.
501
205720
void BindingData::NumberImpl(BindingData* receiver) {
502
  // Make sure we don't accidentally access buffers wiped for snapshot.
503
205720
  CHECK(!receiver->array_buffer_.IsEmpty());
504
205720
  uint64_t t = uv_hrtime();
505
205720
  uint32_t* fields = static_cast<uint32_t*>(receiver->backing_store_->Data());
506
205720
  fields[0] = (t / NANOS_PER_SEC) >> 32;
507
205720
  fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
508
205720
  fields[2] = t % NANOS_PER_SEC;
509
205720
}
510
511
256079
void BindingData::BigIntImpl(BindingData* receiver) {
512
  // Make sure we don't accidentally access buffers wiped for snapshot.
513
256079
  CHECK(!receiver->array_buffer_.IsEmpty());
514
256079
  uint64_t t = uv_hrtime();
515
256079
  uint64_t* fields = static_cast<uint64_t*>(receiver->backing_store_->Data());
516
256079
  fields[0] = t;
517
256079
}
518
519
256079
void BindingData::SlowBigInt(const FunctionCallbackInfo<Value>& args) {
520
256079
  BigIntImpl(FromJSObject<BindingData>(args.Holder()));
521
256079
}
522
523
205720
void BindingData::SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args) {
524
205720
  NumberImpl(FromJSObject<BindingData>(args.Holder()));
525
205720
}
526
527
6
bool BindingData::PrepareForSerialization(Local<Context> context,
528
                                          v8::SnapshotCreator* creator) {
529
  // It's not worth keeping.
530
  // Release it, we will recreate it when the instance is dehydrated.
531
6
  array_buffer_.Reset();
532
  // Return true because we need to maintain the reference to the binding from
533
  // JS land.
534
6
  return true;
535
}
536
537
6
InternalFieldInfoBase* BindingData::Serialize(int index) {
538
  DCHECK_EQ(index, BaseObject::kEmbedderType);
539
  InternalFieldInfo* info =
540
6
      InternalFieldInfoBase::New<InternalFieldInfo>(type());
541
6
  return info;
542
}
543
544
5408
void BindingData::Deserialize(Local<Context> context,
545
                              Local<Object> holder,
546
                              int index,
547
                              InternalFieldInfoBase* info) {
548
  DCHECK_EQ(index, BaseObject::kEmbedderType);
549
10816
  v8::HandleScope scope(context->GetIsolate());
550
5408
  Environment* env = Environment::GetCurrent(context);
551
  // Recreate the buffer in the constructor.
552
5408
  BindingData* binding = env->AddBindingData<BindingData>(context, holder);
553
5408
  CHECK_NOT_NULL(binding);
554
5408
}
555
556
781
static void Initialize(Local<Object> target,
557
                       Local<Value> unused,
558
                       Local<Context> context,
559
                       void* priv) {
560
781
  Environment* env = Environment::GetCurrent(context);
561
  BindingData* const binding_data =
562
781
      env->AddBindingData<BindingData>(context, target);
563
781
  if (binding_data == nullptr) return;
564
781
  binding_data->AddMethods();
565
566
  // define various internal methods
567
781
  if (env->owns_process_state()) {
568
56
    SetMethod(context, target, "_debugProcess", DebugProcess);
569
56
    SetMethod(context, target, "_debugEnd", DebugEnd);
570
56
    SetMethod(context, target, "abort", Abort);
571
56
    SetMethod(context, target, "causeSegfault", CauseSegfault);
572
56
    SetMethod(context, target, "chdir", Chdir);
573
  }
574
575
781
  SetMethod(context, target, "umask", Umask);
576
781
  SetMethod(context, target, "_rawDebug", RawDebug);
577
781
  SetMethod(context, target, "memoryUsage", MemoryUsage);
578
781
  SetMethod(context, target, "rss", Rss);
579
781
  SetMethod(context, target, "cpuUsage", CPUUsage);
580
781
  SetMethod(context, target, "resourceUsage", ResourceUsage);
581
582
781
  SetMethod(context, target, "_getActiveRequestsInfo", GetActiveRequestsInfo);
583
781
  SetMethod(context, target, "_getActiveRequests", GetActiveRequests);
584
781
  SetMethod(context, target, "_getActiveHandles", GetActiveHandles);
585
781
  SetMethod(context, target, "_getActiveHandlesInfo", GetActiveHandlesInfo);
586
781
  SetMethod(context, target, "_kill", Kill);
587
588
781
  SetMethodNoSideEffect(context, target, "cwd", Cwd);
589
781
  SetMethod(context, target, "dlopen", binding::DLOpen);
590
781
  SetMethod(context, target, "reallyExit", ReallyExit);
591
781
  SetMethodNoSideEffect(context, target, "uptime", Uptime);
592
781
  SetMethod(context, target, "patchProcessObject", PatchProcessObject);
593
}
594
595
5415
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
596
5415
  BindingData::RegisterExternalReferences(registry);
597
598
5415
  registry->Register(DebugProcess);
599
5415
  registry->Register(DebugEnd);
600
5415
  registry->Register(Abort);
601
5415
  registry->Register(CauseSegfault);
602
5415
  registry->Register(Chdir);
603
604
5415
  registry->Register(Umask);
605
5415
  registry->Register(RawDebug);
606
5415
  registry->Register(MemoryUsage);
607
5415
  registry->Register(Rss);
608
5415
  registry->Register(CPUUsage);
609
5415
  registry->Register(ResourceUsage);
610
611
5415
  registry->Register(GetActiveRequests);
612
5415
  registry->Register(GetActiveRequestsInfo);
613
5415
  registry->Register(GetActiveHandles);
614
5415
  registry->Register(GetActiveHandlesInfo);
615
5415
  registry->Register(Kill);
616
617
5415
  registry->Register(Cwd);
618
5415
  registry->Register(binding::DLOpen);
619
5415
  registry->Register(ReallyExit);
620
5415
  registry->Register(Uptime);
621
5415
  registry->Register(PatchProcessObject);
622
5415
}
623
624
}  // namespace process
625
}  // namespace node
626
627
5487
NODE_MODULE_CONTEXT_AWARE_INTERNAL(process_methods, node::process::Initialize)
628
5415
NODE_MODULE_EXTERNAL_REFERENCE(process_methods,
629
                               node::process::RegisterExternalReferences)