GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_process_methods.cc Lines: 288 300 96.0 %
Date: 2022-12-07 04:23:16 Branches: 74 114 64.9 %

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::Maybe;
49
using v8::NewStringType;
50
using v8::Number;
51
using v8::Object;
52
using v8::String;
53
using v8::Uint32;
54
using v8::Value;
55
56
namespace per_process {
57
Mutex umask_mutex;
58
}   // namespace per_process
59
60
// Microseconds in a second, as a float, used in CPUUsage() below
61
#define MICROS_PER_SEC 1e6
62
// used in Hrtime() and Uptime() below
63
#define NANOS_PER_SEC 1000000000
64
65
static void Abort(const FunctionCallbackInfo<Value>& args) {
66
  Abort();
67
}
68
69
// For internal testing only, not exposed to userland.
70
static void CauseSegfault(const FunctionCallbackInfo<Value>& args) {
71
  // This should crash hard all platforms.
72
  volatile void** d = static_cast<volatile void**>(nullptr);
73
  *d = nullptr;
74
}
75
76
532
static void Chdir(const FunctionCallbackInfo<Value>& args) {
77
532
  Environment* env = Environment::GetCurrent(args);
78
532
  CHECK(env->owns_process_state());
79
80
532
  CHECK_EQ(args.Length(), 1);
81
1064
  CHECK(args[0]->IsString());
82
532
  Utf8Value path(env->isolate(), args[0]);
83
532
  int err = uv_chdir(*path);
84
532
  if (err) {
85
    // Also include the original working directory, since that will usually
86
    // be helpful information when debugging a `chdir()` failure.
87
    char buf[PATH_MAX_BYTES];
88
1
    size_t cwd_len = sizeof(buf);
89
1
    uv_cwd(buf, &cwd_len);
90
1
    return env->ThrowUVException(err, "chdir", nullptr, buf, *path);
91
  }
92
}
93
94
558
inline Local<ArrayBuffer> get_fields_array_buffer(
95
    const FunctionCallbackInfo<Value>& args,
96
    size_t index,
97
    size_t array_length) {
98

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



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


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

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

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