GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/out/../src/node.cc Lines: 1246 1560 79.9 %
Date: 2017-01-02 Branches: 574 959 59.9 %

Line Branch Exec Source
1
#include "node.h"
2
#include "node_buffer.h"
3
#include "node_constants.h"
4
#include "node_file.h"
5
#include "node_http_parser.h"
6
#include "node_javascript.h"
7
#include "node_version.h"
8
#include "node_internals.h"
9
#include "node_revert.h"
10
#include "node_debug_options.h"
11
12
#if defined HAVE_PERFCTR
13
#include "node_counters.h"
14
#endif
15
16
#if HAVE_OPENSSL
17
#include "node_crypto.h"
18
#endif
19
20
#if defined(NODE_HAVE_I18N_SUPPORT)
21
#include "node_i18n.h"
22
#endif
23
24
#if defined HAVE_DTRACE || defined HAVE_ETW
25
#include "node_dtrace.h"
26
#endif
27
28
#if defined HAVE_LTTNG
29
#include "node_lttng.h"
30
#endif
31
32
#include "ares.h"
33
#include "async-wrap.h"
34
#include "async-wrap-inl.h"
35
#include "env.h"
36
#include "env-inl.h"
37
#include "handle_wrap.h"
38
#include "req-wrap.h"
39
#include "req-wrap-inl.h"
40
#include "string_bytes.h"
41
#include "tracing/agent.h"
42
#include "util.h"
43
#include "uv.h"
44
#if NODE_USE_V8_PLATFORM
45
#include "libplatform/libplatform.h"
46
#endif  // NODE_USE_V8_PLATFORM
47
#include "v8-debug.h"
48
#include "v8-profiler.h"
49
#include "zlib.h"
50
51
#ifdef NODE_ENABLE_VTUNE_PROFILING
52
#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
53
#endif
54
55
#include <errno.h>
56
#include <limits.h>  // PATH_MAX
57
#include <locale.h>
58
#include <signal.h>
59
#include <stdio.h>
60
#include <stdlib.h>
61
#include <string.h>
62
#include <sys/types.h>
63
64
#include <string>
65
#include <vector>
66
67
#if defined(NODE_HAVE_I18N_SUPPORT)
68
#include <unicode/uvernum.h>
69
#endif
70
71
#if defined(LEAK_SANITIZER)
72
#include <sanitizer/lsan_interface.h>
73
#endif
74
75
#if defined(_MSC_VER)
76
#include <direct.h>
77
#include <io.h>
78
#define getpid GetCurrentProcessId
79
#define umask _umask
80
typedef int mode_t;
81
#else
82
#include <pthread.h>
83
#include <sys/resource.h>  // getrlimit, setrlimit
84
#include <unistd.h>  // setuid, getuid
85
#endif
86
87
#if defined(__POSIX__) && !defined(__ANDROID__)
88
#include <pwd.h>  // getpwnam()
89
#include <grp.h>  // getgrnam()
90
#endif
91
92
#ifdef __APPLE__
93
#include <crt_externs.h>
94
#define environ (*_NSGetEnviron())
95
#elif !defined(_MSC_VER)
96
extern char **environ;
97
#endif
98
99
namespace node {
100
101
using v8::Array;
102
using v8::ArrayBuffer;
103
using v8::Boolean;
104
using v8::Context;
105
using v8::EscapableHandleScope;
106
using v8::Exception;
107
using v8::Float64Array;
108
using v8::Function;
109
using v8::FunctionCallbackInfo;
110
using v8::HandleScope;
111
using v8::HeapStatistics;
112
using v8::Integer;
113
using v8::Isolate;
114
using v8::Local;
115
using v8::Locker;
116
using v8::MaybeLocal;
117
using v8::Message;
118
using v8::Name;
119
using v8::NamedPropertyHandlerConfiguration;
120
using v8::Null;
121
using v8::Number;
122
using v8::Object;
123
using v8::ObjectTemplate;
124
using v8::Promise;
125
using v8::PromiseRejectMessage;
126
using v8::PropertyCallbackInfo;
127
using v8::ScriptOrigin;
128
using v8::SealHandleScope;
129
using v8::String;
130
using v8::TryCatch;
131
using v8::Uint32Array;
132
using v8::V8;
133
using v8::Value;
134
135
static bool print_eval = false;
136
static bool force_repl = false;
137
static bool syntax_check_only = false;
138
static bool trace_deprecation = false;
139
static bool throw_deprecation = false;
140
static bool trace_sync_io = false;
141
static bool track_heap_objects = false;
142
static const char* eval_string = nullptr;
143
static unsigned int preload_module_count = 0;
144
static const char** preload_modules = nullptr;
145
static const int v8_default_thread_pool_size = 4;
146
static int v8_thread_pool_size = v8_default_thread_pool_size;
147
static bool prof_process = false;
148
static bool v8_is_profiling = false;
149
static bool node_is_initialized = false;
150
static node_module* modpending;
151
static node_module* modlist_builtin;
152
static node_module* modlist_linked;
153
static node_module* modlist_addon;
154
static bool trace_enabled = false;
155
static const char* trace_enabled_categories = nullptr;
156
157
#if defined(NODE_HAVE_I18N_SUPPORT)
158
// Path to ICU data (for i18n / Intl)
159
static const char* icu_data_dir = nullptr;
160
#endif
161
162
// used by C++ modules as well
163
bool no_deprecation = false;
164
165
#if HAVE_OPENSSL
166
# if NODE_FIPS_MODE
167
// used by crypto module
168
bool enable_fips_crypto = false;
169
bool force_fips_crypto = false;
170
# endif  // NODE_FIPS_MODE
171
const char* openssl_config = nullptr;
172
#endif  // HAVE_OPENSSL
173
174
// true if process warnings should be suppressed
175
bool no_process_warnings = false;
176
bool trace_warnings = false;
177
178
// Set in node.cc by ParseArgs when --preserve-symlinks is used.
179
// Used in node_config.cc to set a constant on process.binding('config')
180
// that is used by lib/module.js
181
bool config_preserve_symlinks = false;
182
183
bool v8_initialized = false;
184
185
// process-relative uptime base, initialized at start-up
186
static double prog_start_time;
187
static bool debugger_running;
188
static uv_async_t dispatch_debug_messages_async;
189
190
1757
static Mutex node_isolate_mutex;
191
static v8::Isolate* node_isolate;
192
static tracing::Agent* tracing_agent;
193
194
1757
static node::DebugOptions debug_options;
195
196
static struct {
197
#if NODE_USE_V8_PLATFORM
198
1744
  void Initialize(int thread_pool_size) {
199
1744
    platform_ = v8::platform::CreateDefaultPlatform(thread_pool_size);
200
1744
    V8::InitializePlatform(platform_);
201
1744
    tracing::TraceEventHelper::SetCurrentPlatform(platform_);
202
1744
  }
203
204
  void PumpMessageLoop(Isolate* isolate) {
205
24578
    v8::platform::PumpMessageLoop(platform_, isolate);
206
  }
207
208
  void Dispose() {
209
1544
    delete platform_;
210
1544
    platform_ = nullptr;
211
  }
212
213
#if HAVE_INSPECTOR
214
  bool StartInspector(Environment *env, const char* script_path,
215
                      const node::DebugOptions& options) {
216
14
    return env->inspector_agent()->Start(platform_, script_path, options);
217
  }
218
#endif  // HAVE_INSPECTOR
219
220
  v8::Platform* platform_;
221
#else  // !NODE_USE_V8_PLATFORM
222
  void Initialize(int thread_pool_size) {}
223
  void PumpMessageLoop(Isolate* isolate) {}
224
  void Dispose() {}
225
  bool StartInspector(Environment *env, const char* script_path,
226
                      int port, bool wait) {
227
    env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
228
    return false;  // make compiler happy
229
  }
230
#endif  // !NODE_USE_V8_PLATFORM
231
} v8_platform;
232
233
#ifdef __POSIX__
234
static uv_sem_t debug_semaphore;
235
static const unsigned kMaxSignal = 32;
236
#endif
237
238
78
static void PrintErrorString(const char* format, ...) {
239
  va_list ap;
240
78
  va_start(ap, format);
241
#ifdef _WIN32
242
  HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
243
244
  // Check if stderr is something other than a tty/console
245
  if (stderr_handle == INVALID_HANDLE_VALUE ||
246
      stderr_handle == nullptr ||
247
      uv_guess_handle(_fileno(stderr)) != UV_TTY) {
248
    vfprintf(stderr, format, ap);
249
    va_end(ap);
250
    return;
251
  }
252
253
  // Fill in any placeholders
254
  int n = _vscprintf(format, ap);
255
  std::vector<char> out(n + 1);
256
  vsprintf(out.data(), format, ap);
257
258
  // Get required wide buffer size
259
  n = MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, nullptr, 0);
260
261
  std::vector<wchar_t> wbuf(n);
262
  MultiByteToWideChar(CP_UTF8, 0, out.data(), -1, wbuf.data(), n);
263
264
  // Don't include the null character in the output
265
  CHECK_GT(n, 0);
266
  WriteConsoleW(stderr_handle, wbuf.data(), n - 1, nullptr, nullptr);
267
#else
268
156
  vfprintf(stderr, format, ap);
269
#endif
270
78
  va_end(ap);
271
78
}
272
273
274
3126
static void CheckImmediate(uv_check_t* handle) {
275
3126
  Environment* env = Environment::from_immediate_check_handle(handle);
276
6236
  HandleScope scope(env->isolate());
277
9362
  Context::Scope context_scope(env->context());
278
6252
  MakeCallback(env, env->process_object(), env->immediate_callback_string());
279
3110
}
280
281
282
2062
static void IdleImmediateDummy(uv_idle_t* handle) {
283
  // Do nothing. Only for maintaining event loop.
284
  // TODO(bnoordhuis) Maybe make libuv accept nullptr idle callbacks.
285
2062
}
286
287
288
static inline const char *errno_string(int errorno) {
289
#define ERRNO_CASE(e)  case e: return #e;
290
1
  switch (errorno) {
291
#ifdef EACCES
292
  ERRNO_CASE(EACCES);
293
#endif
294
295
#ifdef EADDRINUSE
296
  ERRNO_CASE(EADDRINUSE);
297
#endif
298
299
#ifdef EADDRNOTAVAIL
300
  ERRNO_CASE(EADDRNOTAVAIL);
301
#endif
302
303
#ifdef EAFNOSUPPORT
304
  ERRNO_CASE(EAFNOSUPPORT);
305
#endif
306
307
#ifdef EAGAIN
308
  ERRNO_CASE(EAGAIN);
309
#endif
310
311
#ifdef EWOULDBLOCK
312
# if EAGAIN != EWOULDBLOCK
313
  ERRNO_CASE(EWOULDBLOCK);
314
# endif
315
#endif
316
317
#ifdef EALREADY
318
  ERRNO_CASE(EALREADY);
319
#endif
320
321
#ifdef EBADF
322
  ERRNO_CASE(EBADF);
323
#endif
324
325
#ifdef EBADMSG
326
  ERRNO_CASE(EBADMSG);
327
#endif
328
329
#ifdef EBUSY
330
  ERRNO_CASE(EBUSY);
331
#endif
332
333
#ifdef ECANCELED
334
  ERRNO_CASE(ECANCELED);
335
#endif
336
337
#ifdef ECHILD
338
  ERRNO_CASE(ECHILD);
339
#endif
340
341
#ifdef ECONNABORTED
342
  ERRNO_CASE(ECONNABORTED);
343
#endif
344
345
#ifdef ECONNREFUSED
346
  ERRNO_CASE(ECONNREFUSED);
347
#endif
348
349
#ifdef ECONNRESET
350
  ERRNO_CASE(ECONNRESET);
351
#endif
352
353
#ifdef EDEADLK
354
  ERRNO_CASE(EDEADLK);
355
#endif
356
357
#ifdef EDESTADDRREQ
358
  ERRNO_CASE(EDESTADDRREQ);
359
#endif
360
361
#ifdef EDOM
362
  ERRNO_CASE(EDOM);
363
#endif
364
365
#ifdef EDQUOT
366
  ERRNO_CASE(EDQUOT);
367
#endif
368
369
#ifdef EEXIST
370
  ERRNO_CASE(EEXIST);
371
#endif
372
373
#ifdef EFAULT
374
  ERRNO_CASE(EFAULT);
375
#endif
376
377
#ifdef EFBIG
378
  ERRNO_CASE(EFBIG);
379
#endif
380
381
#ifdef EHOSTUNREACH
382
  ERRNO_CASE(EHOSTUNREACH);
383
#endif
384
385
#ifdef EIDRM
386
  ERRNO_CASE(EIDRM);
387
#endif
388
389
#ifdef EILSEQ
390
  ERRNO_CASE(EILSEQ);
391
#endif
392
393
#ifdef EINPROGRESS
394
  ERRNO_CASE(EINPROGRESS);
395
#endif
396
397
#ifdef EINTR
398
  ERRNO_CASE(EINTR);
399
#endif
400
401
#ifdef EINVAL
402
  ERRNO_CASE(EINVAL);
403
#endif
404
405
#ifdef EIO
406
  ERRNO_CASE(EIO);
407
#endif
408
409
#ifdef EISCONN
410
  ERRNO_CASE(EISCONN);
411
#endif
412
413
#ifdef EISDIR
414
  ERRNO_CASE(EISDIR);
415
#endif
416
417
#ifdef ELOOP
418
  ERRNO_CASE(ELOOP);
419
#endif
420
421
#ifdef EMFILE
422
  ERRNO_CASE(EMFILE);
423
#endif
424
425
#ifdef EMLINK
426
  ERRNO_CASE(EMLINK);
427
#endif
428
429
#ifdef EMSGSIZE
430
  ERRNO_CASE(EMSGSIZE);
431
#endif
432
433
#ifdef EMULTIHOP
434
  ERRNO_CASE(EMULTIHOP);
435
#endif
436
437
#ifdef ENAMETOOLONG
438
  ERRNO_CASE(ENAMETOOLONG);
439
#endif
440
441
#ifdef ENETDOWN
442
  ERRNO_CASE(ENETDOWN);
443
#endif
444
445
#ifdef ENETRESET
446
  ERRNO_CASE(ENETRESET);
447
#endif
448
449
#ifdef ENETUNREACH
450
  ERRNO_CASE(ENETUNREACH);
451
#endif
452
453
#ifdef ENFILE
454
  ERRNO_CASE(ENFILE);
455
#endif
456
457
#ifdef ENOBUFS
458
  ERRNO_CASE(ENOBUFS);
459
#endif
460
461
#ifdef ENODATA
462
  ERRNO_CASE(ENODATA);
463
#endif
464
465
#ifdef ENODEV
466
  ERRNO_CASE(ENODEV);
467
#endif
468
469
#ifdef ENOENT
470
  ERRNO_CASE(ENOENT);
471
#endif
472
473
#ifdef ENOEXEC
474
  ERRNO_CASE(ENOEXEC);
475
#endif
476
477
#ifdef ENOLINK
478
  ERRNO_CASE(ENOLINK);
479
#endif
480
481
#ifdef ENOLCK
482
# if ENOLINK != ENOLCK
483
  ERRNO_CASE(ENOLCK);
484
# endif
485
#endif
486
487
#ifdef ENOMEM
488
  ERRNO_CASE(ENOMEM);
489
#endif
490
491
#ifdef ENOMSG
492
  ERRNO_CASE(ENOMSG);
493
#endif
494
495
#ifdef ENOPROTOOPT
496
  ERRNO_CASE(ENOPROTOOPT);
497
#endif
498
499
#ifdef ENOSPC
500
  ERRNO_CASE(ENOSPC);
501
#endif
502
503
#ifdef ENOSR
504
  ERRNO_CASE(ENOSR);
505
#endif
506
507
#ifdef ENOSTR
508
  ERRNO_CASE(ENOSTR);
509
#endif
510
511
#ifdef ENOSYS
512
  ERRNO_CASE(ENOSYS);
513
#endif
514
515
#ifdef ENOTCONN
516
  ERRNO_CASE(ENOTCONN);
517
#endif
518
519
#ifdef ENOTDIR
520
  ERRNO_CASE(ENOTDIR);
521
#endif
522
523
#ifdef ENOTEMPTY
524
# if ENOTEMPTY != EEXIST
525
  ERRNO_CASE(ENOTEMPTY);
526
# endif
527
#endif
528
529
#ifdef ENOTSOCK
530
  ERRNO_CASE(ENOTSOCK);
531
#endif
532
533
#ifdef ENOTSUP
534
  ERRNO_CASE(ENOTSUP);
535
#else
536
# ifdef EOPNOTSUPP
537
  ERRNO_CASE(EOPNOTSUPP);
538
# endif
539
#endif
540
541
#ifdef ENOTTY
542
  ERRNO_CASE(ENOTTY);
543
#endif
544
545
#ifdef ENXIO
546
  ERRNO_CASE(ENXIO);
547
#endif
548
549
550
#ifdef EOVERFLOW
551
  ERRNO_CASE(EOVERFLOW);
552
#endif
553
554
#ifdef EPERM
555
  ERRNO_CASE(EPERM);
556
#endif
557
558
#ifdef EPIPE
559
  ERRNO_CASE(EPIPE);
560
#endif
561
562
#ifdef EPROTO
563
  ERRNO_CASE(EPROTO);
564
#endif
565
566
#ifdef EPROTONOSUPPORT
567
  ERRNO_CASE(EPROTONOSUPPORT);
568
#endif
569
570
#ifdef EPROTOTYPE
571
  ERRNO_CASE(EPROTOTYPE);
572
#endif
573
574
#ifdef ERANGE
575
  ERRNO_CASE(ERANGE);
576
#endif
577
578
#ifdef EROFS
579
  ERRNO_CASE(EROFS);
580
#endif
581
582
#ifdef ESPIPE
583
  ERRNO_CASE(ESPIPE);
584
#endif
585
586
#ifdef ESRCH
587
  ERRNO_CASE(ESRCH);
588
#endif
589
590
#ifdef ESTALE
591
  ERRNO_CASE(ESTALE);
592
#endif
593
594
#ifdef ETIME
595
  ERRNO_CASE(ETIME);
596
#endif
597
598
#ifdef ETIMEDOUT
599
  ERRNO_CASE(ETIMEDOUT);
600
#endif
601
602
#ifdef ETXTBSY
603
  ERRNO_CASE(ETXTBSY);
604
#endif
605
606
#ifdef EXDEV
607
  ERRNO_CASE(EXDEV);
608
#endif
609
610
  default: return "";
611
  }
612
}
613
614
682
const char *signo_string(int signo) {
615
#define SIGNO_CASE(e)  case e: return #e;
616
682
  switch (signo) {
617
#ifdef SIGHUP
618
  SIGNO_CASE(SIGHUP);
619
#endif
620
621
#ifdef SIGINT
622
  SIGNO_CASE(SIGINT);
623
#endif
624
625
#ifdef SIGQUIT
626
  SIGNO_CASE(SIGQUIT);
627
#endif
628
629
#ifdef SIGILL
630
  SIGNO_CASE(SIGILL);
631
#endif
632
633
#ifdef SIGTRAP
634
  SIGNO_CASE(SIGTRAP);
635
#endif
636
637
#ifdef SIGABRT
638
  SIGNO_CASE(SIGABRT);
639
#endif
640
641
#ifdef SIGIOT
642
# if SIGABRT != SIGIOT
643
  SIGNO_CASE(SIGIOT);
644
# endif
645
#endif
646
647
#ifdef SIGBUS
648
  SIGNO_CASE(SIGBUS);
649
#endif
650
651
#ifdef SIGFPE
652
  SIGNO_CASE(SIGFPE);
653
#endif
654
655
#ifdef SIGKILL
656
  SIGNO_CASE(SIGKILL);
657
#endif
658
659
#ifdef SIGUSR1
660
  SIGNO_CASE(SIGUSR1);
661
#endif
662
663
#ifdef SIGSEGV
664
  SIGNO_CASE(SIGSEGV);
665
#endif
666
667
#ifdef SIGUSR2
668
  SIGNO_CASE(SIGUSR2);
669
#endif
670
671
#ifdef SIGPIPE
672
  SIGNO_CASE(SIGPIPE);
673
#endif
674
675
#ifdef SIGALRM
676
  SIGNO_CASE(SIGALRM);
677
#endif
678
679
  SIGNO_CASE(SIGTERM);
680
681
#ifdef SIGCHLD
682
  SIGNO_CASE(SIGCHLD);
683
#endif
684
685
#ifdef SIGSTKFLT
686
  SIGNO_CASE(SIGSTKFLT);
687
#endif
688
689
690
#ifdef SIGCONT
691
  SIGNO_CASE(SIGCONT);
692
#endif
693
694
#ifdef SIGSTOP
695
  SIGNO_CASE(SIGSTOP);
696
#endif
697
698
#ifdef SIGTSTP
699
  SIGNO_CASE(SIGTSTP);
700
#endif
701
702
#ifdef SIGBREAK
703
  SIGNO_CASE(SIGBREAK);
704
#endif
705
706
#ifdef SIGTTIN
707
  SIGNO_CASE(SIGTTIN);
708
#endif
709
710
#ifdef SIGTTOU
711
  SIGNO_CASE(SIGTTOU);
712
#endif
713
714
#ifdef SIGURG
715
  SIGNO_CASE(SIGURG);
716
#endif
717
718
#ifdef SIGXCPU
719
  SIGNO_CASE(SIGXCPU);
720
#endif
721
722
#ifdef SIGXFSZ
723
  SIGNO_CASE(SIGXFSZ);
724
#endif
725
726
#ifdef SIGVTALRM
727
  SIGNO_CASE(SIGVTALRM);
728
#endif
729
730
#ifdef SIGPROF
731
  SIGNO_CASE(SIGPROF);
732
#endif
733
734
#ifdef SIGWINCH
735
  SIGNO_CASE(SIGWINCH);
736
#endif
737
738
#ifdef SIGIO
739
  SIGNO_CASE(SIGIO);
740
#endif
741
742
#ifdef SIGPOLL
743
# if SIGPOLL != SIGIO
744
  SIGNO_CASE(SIGPOLL);
745
# endif
746
#endif
747
748
#ifdef SIGLOST
749
# if SIGLOST != SIGABRT
750
  SIGNO_CASE(SIGLOST);
751
# endif
752
#endif
753
754
#ifdef SIGPWR
755
# if SIGPWR != SIGLOST
756
  SIGNO_CASE(SIGPWR);
757
# endif
758
#endif
759
760
#ifdef SIGINFO
761
# if !defined(SIGPWR) || SIGINFO != SIGPWR
762
  SIGNO_CASE(SIGINFO);
763
# endif
764
#endif
765
766
#ifdef SIGSYS
767
  SIGNO_CASE(SIGSYS);
768
#endif
769
770
  default: return "";
771
  }
772
}
773
774
775
1
Local<Value> ErrnoException(Isolate* isolate,
776
                            int errorno,
777
                            const char *syscall,
778
                            const char *msg,
779
                            const char *path) {
780
1
  Environment* env = Environment::GetCurrent(isolate);
781
782
1
  Local<Value> e;
783
1
  Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
784

1
  if (msg == nullptr || msg[0] == '\0') {
785
1
    msg = strerror(errorno);
786
  }
787
1
  Local<String> message = OneByteString(env->isolate(), msg);
788
789
  Local<String> cons =
790
1
      String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
791
1
  cons = String::Concat(cons, message);
792
793
1
  Local<String> path_string;
794
1
  if (path != nullptr) {
795
    // FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8.
796
    path_string = String::NewFromUtf8(env->isolate(), path);
797
  }
798
799
1
  if (path_string.IsEmpty() == false) {
800
    cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
801
    cons = String::Concat(cons, path_string);
802
    cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
803
  }
804
1
  e = Exception::Error(cons);
805
806
1
  Local<Object> obj = e->ToObject(env->isolate());
807
4
  obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
808
3
  obj->Set(env->code_string(), estring);
809
810
1
  if (path_string.IsEmpty() == false) {
811
    obj->Set(env->path_string(), path_string);
812
  }
813
814
1
  if (syscall != nullptr) {
815
4
    obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
816
  }
817
818
1
  return e;
819
}
820
821
822
static Local<String> StringFromPath(Isolate* isolate, const char* path) {
823
#ifdef _WIN32
824
  if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
825
    return String::Concat(FIXED_ONE_BYTE_STRING(isolate, "\\\\"),
826
                          String::NewFromUtf8(isolate, path + 8));
827
  } else if (strncmp(path, "\\\\?\\", 4) == 0) {
828
    return String::NewFromUtf8(isolate, path + 4);
829
  }
830
#endif
831
832
2508
  return String::NewFromUtf8(isolate, path);
833
}
834
835
836
Local<Value> UVException(Isolate* isolate,
837
                         int errorno,
838
                         const char* syscall,
839
                         const char* msg,
840
                         const char* path) {
841
  return UVException(isolate, errorno, syscall, msg, path, nullptr);
842
}
843
844
845
2518
Local<Value> UVException(Isolate* isolate,
846
                         int errorno,
847
                         const char* syscall,
848
                         const char* msg,
849
                         const char* path,
850
                         const char* dest) {
851
2518
  Environment* env = Environment::GetCurrent(isolate);
852
853

2518
  if (!msg || !msg[0])
854
2518
    msg = uv_strerror(errorno);
855
856
2518
  Local<String> js_code = OneByteString(isolate, uv_err_name(errorno));
857
2518
  Local<String> js_syscall = OneByteString(isolate, syscall);
858
2518
  Local<String> js_path;
859
2518
  Local<String> js_dest;
860
861
2518
  Local<String> js_msg = js_code;
862
2518
  js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ": "));
863
2518
  js_msg = String::Concat(js_msg, OneByteString(isolate, msg));
864
2518
  js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
865
2518
  js_msg = String::Concat(js_msg, js_syscall);
866
867
2518
  if (path != nullptr) {
868
2498
    js_path = StringFromPath(isolate, path);
869
870
2498
    js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " '"));
871
2498
    js_msg = String::Concat(js_msg, js_path);
872
2498
    js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
873
  }
874
875
2518
  if (dest != nullptr) {
876
10
    js_dest = StringFromPath(isolate, dest);
877
878
10
    js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '"));
879
10
    js_msg = String::Concat(js_msg, js_dest);
880
10
    js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
881
  }
882
883
5036
  Local<Object> e = Exception::Error(js_msg)->ToObject(isolate);
884
885
  // TODO(piscisaureus) errno should probably go; the user has no way of
886
  // knowing which uv errno value maps to which error.
887
10072
  e->Set(env->errno_string(), Integer::New(isolate, errorno));
888
7554
  e->Set(env->code_string(), js_code);
889
7554
  e->Set(env->syscall_string(), js_syscall);
890
2518
  if (!js_path.IsEmpty())
891
7494
    e->Set(env->path_string(), js_path);
892
2518
  if (!js_dest.IsEmpty())
893
30
    e->Set(env->dest_string(), js_dest);
894
895
2518
  return e;
896
}
897
898
899
// Look up environment variable unless running as setuid root.
900
5255
inline const char* secure_getenv(const char* key) {
901
#ifndef _WIN32
902

5255
  if (getuid() != geteuid() || getgid() != getegid())
903
    return nullptr;
904
#endif
905
5255
  return getenv(key);
906
}
907
908
909
#ifdef _WIN32
910
// Does about the same as strerror(),
911
// but supports all windows error messages
912
static const char *winapi_strerror(const int errorno, bool* must_free) {
913
  char *errmsg = nullptr;
914
915
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
916
      FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
917
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
918
919
  if (errmsg) {
920
    *must_free = true;
921
922
    // Remove trailing newlines
923
    for (int i = strlen(errmsg) - 1;
924
        i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
925
      errmsg[i] = '\0';
926
    }
927
928
    return errmsg;
929
  } else {
930
    // FormatMessage failed
931
    *must_free = false;
932
    return "Unknown error";
933
  }
934
}
935
936
937
Local<Value> WinapiErrnoException(Isolate* isolate,
938
                                  int errorno,
939
                                  const char* syscall,
940
                                  const char* msg,
941
                                  const char* path) {
942
  Environment* env = Environment::GetCurrent(isolate);
943
  Local<Value> e;
944
  bool must_free = false;
945
  if (!msg || !msg[0]) {
946
    msg = winapi_strerror(errorno, &must_free);
947
  }
948
  Local<String> message = OneByteString(env->isolate(), msg);
949
950
  if (path) {
951
    Local<String> cons1 =
952
        String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '"));
953
    Local<String> cons2 =
954
        String::Concat(cons1, String::NewFromUtf8(isolate, path));
955
    Local<String> cons3 =
956
        String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
957
    e = Exception::Error(cons3);
958
  } else {
959
    e = Exception::Error(message);
960
  }
961
962
  Local<Object> obj = e->ToObject(env->isolate());
963
  obj->Set(env->errno_string(), Integer::New(isolate, errorno));
964
965
  if (path != nullptr) {
966
    obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
967
  }
968
969
  if (syscall != nullptr) {
970
    obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
971
  }
972
973
  if (must_free)
974
    LocalFree((HLOCAL)msg);
975
976
  return e;
977
}
978
#endif
979
980
981
13873
void* ArrayBufferAllocator::Allocate(size_t size) {
982

13873
  if (zero_fill_field_ || zero_fill_all_buffers)
983
5542
    return node::UncheckedCalloc(size);
984
  else
985
8331
    return node::UncheckedMalloc(size);
986
}
987
988
28
static bool DomainHasErrorHandler(const Environment* env,
989
                                  const Local<Object>& domain) {
990
56
  HandleScope scope(env->isolate());
991
992
84
  Local<Value> domain_event_listeners_v = domain->Get(env->events_string());
993
28
  if (!domain_event_listeners_v->IsObject())
994
    return false;
995
996
  Local<Object> domain_event_listeners_o =
997
28
      domain_event_listeners_v.As<Object>();
998
999
  Local<Value> domain_error_listeners_v =
1000
56
      domain_event_listeners_o->Get(env->error_string());
1001
1002

57
  if (domain_error_listeners_v->IsFunction() ||
1003
1
      (domain_error_listeners_v->IsArray() &&
1004
      domain_error_listeners_v.As<Array>()->Length() > 0))
1005
    return true;
1006
1007
1
  return false;
1008
}
1009
1010
27
static bool DomainsStackHasErrorHandler(const Environment* env) {
1011
54
  HandleScope scope(env->isolate());
1012
1013
27
  if (!env->using_domains())
1014
    return false;
1015
1016
54
  Local<Array> domains_stack_array = env->domains_stack_array().As<Array>();
1017
27
  if (domains_stack_array->Length() == 0)
1018
    return false;
1019
1020
27
  uint32_t domains_stack_length = domains_stack_array->Length();
1021
28
  for (uint32_t i = domains_stack_length; i > 0; --i) {
1022
28
    Local<Value> domain_v = domains_stack_array->Get(i - 1);
1023
28
    if (!domain_v->IsObject())
1024
27
      return false;
1025
1026
28
    Local<Object> domain = domain_v.As<Object>();
1027
28
    if (DomainHasErrorHandler(env, domain))
1028
      return true;
1029
  }
1030
1031
  return false;
1032
}
1033
1034
1035
27
static bool ShouldAbortOnUncaughtException(Isolate* isolate) {
1036
54
  HandleScope scope(isolate);
1037
1038
27
  Environment* env = Environment::GetCurrent(isolate);
1039
27
  Local<Object> process_object = env->process_object();
1040
  Local<String> emitting_top_level_domain_error_key =
1041
27
    env->emitting_top_level_domain_error_string();
1042
  bool isEmittingTopLevelDomainError =
1043
54
      process_object->Get(emitting_top_level_domain_error_key)->BooleanValue();
1044
1045

54
  return isEmittingTopLevelDomainError || !DomainsStackHasErrorHandler(env);
1046
}
1047
1048
1049
139
void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
1050
139
  Environment* env = Environment::GetCurrent(args);
1051
1052
139
  if (env->using_domains())
1053
    return;
1054
139
  env->set_using_domains(true);
1055
1056
278
  HandleScope scope(env->isolate());
1057
139
  Local<Object> process_object = env->process_object();
1058
1059
139
  Local<String> tick_callback_function_key = env->tick_domain_cb_string();
1060
  Local<Function> tick_callback_function =
1061
278
      process_object->Get(tick_callback_function_key).As<Function>();
1062
1063
139
  if (!tick_callback_function->IsFunction()) {
1064
    fprintf(stderr, "process._tickDomainCallback assigned to non-function\n");
1065
    ABORT();
1066
  }
1067
1068
417
  process_object->Set(env->tick_callback_string(), tick_callback_function);
1069
139
  env->set_tick_callback_function(tick_callback_function);
1070
1071
139
  CHECK(args[0]->IsArray());
1072
278
  env->set_domain_array(args[0].As<Array>());
1073
1074
139
  CHECK(args[1]->IsArray());
1075
278
  env->set_domains_stack_array(args[1].As<Array>());
1076
1077
  // Do a little housekeeping.
1078
417
  env->process_object()->Delete(
1079
      env->context(),
1080
973
      FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse")).FromJust();
1081
1082
278
  uint32_t* const fields = env->domain_flag()->fields();
1083
139
  uint32_t const fields_count = env->domain_flag()->fields_count();
1084
1085
  Local<ArrayBuffer> array_buffer =
1086
139
      ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1087
1088
417
  args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
1089
}
1090
1091
32692
void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
1092
32692
  args.GetIsolate()->RunMicrotasks();
1093
32692
}
1094
1095
1096
1750
void SetupProcessObject(const FunctionCallbackInfo<Value>& args) {
1097
1750
  Environment* env = Environment::GetCurrent(args);
1098
1099
1750
  CHECK(args[0]->IsFunction());
1100
1101
3500
  env->set_push_values_to_array_function(args[0].As<Function>());
1102
5250
  env->process_object()->Delete(
1103
      env->context(),
1104
10500
      FIXED_ONE_BYTE_STRING(env->isolate(), "_setupProcessObject")).FromJust();
1105
1750
}
1106
1107
1108
1750
void SetupNextTick(const FunctionCallbackInfo<Value>& args) {
1109
1750
  Environment* env = Environment::GetCurrent(args);
1110
1111
1750
  CHECK(args[0]->IsFunction());
1112
1750
  CHECK(args[1]->IsObject());
1113
1114
3500
  env->set_tick_callback_function(args[0].As<Function>());
1115
1116
3500
  env->SetMethod(args[1].As<Object>(), "runMicrotasks", RunMicrotasks);
1117
1118
  // Do a little housekeeping.
1119
5250
  env->process_object()->Delete(
1120
      env->context(),
1121
12250
      FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupNextTick")).FromJust();
1122
1123
  // Values use to cross communicate with processNextTick.
1124
3500
  uint32_t* const fields = env->tick_info()->fields();
1125
1750
  uint32_t const fields_count = env->tick_info()->fields_count();
1126
1127
  Local<ArrayBuffer> array_buffer =
1128
1750
      ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count);
1129
1130
5250
  args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count));
1131
1750
}
1132
1133
64
void PromiseRejectCallback(PromiseRejectMessage message) {
1134
64
  Local<Promise> promise = message.GetPromise();
1135
64
  Isolate* isolate = promise->GetIsolate();
1136
64
  Local<Value> value = message.GetValue();
1137
64
  Local<Integer> event = Integer::New(isolate, message.GetEvent());
1138
1139
64
  Environment* env = Environment::GetCurrent(isolate);
1140
64
  Local<Function> callback = env->promise_reject_function();
1141
1142
64
  if (value.IsEmpty())
1143
50
    value = Undefined(isolate);
1144
1145
192
  Local<Value> args[] = { event, promise, value };
1146
64
  Local<Object> process = env->process_object();
1147
1148
128
  callback->Call(process, arraysize(args), args);
1149
64
}
1150
1151
1750
void SetupPromises(const FunctionCallbackInfo<Value>& args) {
1152
1750
  Environment* env = Environment::GetCurrent(args);
1153
1750
  Isolate* isolate = env->isolate();
1154
1155
1750
  CHECK(args[0]->IsFunction());
1156
1157
1750
  isolate->SetPromiseRejectCallback(PromiseRejectCallback);
1158
3500
  env->set_promise_reject_function(args[0].As<Function>());
1159
1160
5250
  env->process_object()->Delete(
1161
      env->context(),
1162
12250
      FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupPromises")).FromJust();
1163
1750
}
1164
1165
1166
6276
Local<Value> MakeCallback(Environment* env,
1167
                          Local<Value> recv,
1168
                          const Local<Function> callback,
1169
                          int argc,
1170
                          Local<Value> argv[]) {
1171
  // If you hit this assertion, you forgot to enter the v8::Context first.
1172
18828
  CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
1173
1174
6276
  Local<Function> pre_fn = env->async_hooks_pre_function();
1175
6276
  Local<Function> post_fn = env->async_hooks_post_function();
1176
12552
  Local<Object> object, domain;
1177
6276
  bool ran_init_callback = false;
1178
6276
  bool has_domain = false;
1179
1180
12534
  Environment::AsyncCallbackScope callback_scope(env);
1181
1182
  // TODO(trevnorris): Adding "_asyncQueue" to the "this" in the init callback
1183
  // is a horrible way to detect usage. Rethink how detection should happen.
1184
6276
  if (recv->IsObject()) {
1185
6276
    object = recv.As<Object>();
1186
12552
    Local<Value> async_queue_v = object->Get(env->async_queue_string());
1187
6276
    if (async_queue_v->IsObject())
1188
      ran_init_callback = true;
1189
  }
1190
1191
6276
  if (env->using_domains()) {
1192
1419
    CHECK(recv->IsObject());
1193
2838
    Local<Value> domain_v = object->Get(env->domain_string());
1194
1419
    has_domain = domain_v->IsObject();
1195
1419
    if (has_domain) {
1196
13
      domain = domain_v.As<Object>();
1197
39
      if (domain->Get(env->disposed_string())->IsTrue())
1198
        return Undefined(env->isolate());
1199
    }
1200
  }
1201
1202
6276
  if (has_domain) {
1203
26
    Local<Value> enter_v = domain->Get(env->enter_string());
1204
13
    if (enter_v->IsFunction()) {
1205
39
      if (enter_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
1206
        FatalError("node::MakeCallback",
1207
                   "domain enter callback threw, please report this");
1208
      }
1209
    }
1210
  }
1211
1212

6276
  if (ran_init_callback && !pre_fn.IsEmpty()) {
1213
    TryCatch try_catch(env->isolate());
1214
    MaybeLocal<Value> ar = pre_fn->Call(env->context(), object, 0, nullptr);
1215
    if (ar.IsEmpty()) {
1216
      ClearFatalExceptionHandlers(env);
1217
      FatalException(env->isolate(), try_catch);
1218
      return Local<Value>();
1219
    }
1220
  }
1221
1222
6276
  Local<Value> ret = callback->Call(recv, argc, argv);
1223
1224

6258
  if (ran_init_callback && !post_fn.IsEmpty()) {
1225
    Local<Value> did_throw = Boolean::New(env->isolate(), ret.IsEmpty());
1226
    // Currently there's no way to retrieve an uid from node::MakeCallback().
1227
    // This needs to be fixed.
1228
    Local<Value> vals[] =
1229
        { Undefined(env->isolate()).As<Value>(), did_throw };
1230
    TryCatch try_catch(env->isolate());
1231
    MaybeLocal<Value> ar =
1232
        post_fn->Call(env->context(), object, arraysize(vals), vals);
1233
    if (ar.IsEmpty()) {
1234
      ClearFatalExceptionHandlers(env);
1235
      FatalException(env->isolate(), try_catch);
1236
      return Local<Value>();
1237
    }
1238
  }
1239
1240
6258
  if (ret.IsEmpty()) {
1241
    // NOTE: For backwards compatibility with public API we return Undefined()
1242
    // if the top level call threw.
1243
1023
    return callback_scope.in_makecallback() ?
1244
2042
        ret : Undefined(env->isolate()).As<Value>();
1245
  }
1246
1247
5235
  if (has_domain) {
1248
20
    Local<Value> exit_v = domain->Get(env->exit_string());
1249
10
    if (exit_v->IsFunction()) {
1250
30
      if (exit_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
1251
        FatalError("node::MakeCallback",
1252
                   "domain exit callback threw, please report this");
1253
      }
1254
    }
1255
  }
1256
1257
5235
  if (callback_scope.in_makecallback()) {
1258
23
    return ret;
1259
  }
1260
1261
5212
  Environment::TickInfo* tick_info = env->tick_info();
1262
1263
5212
  if (tick_info->length() == 0) {
1264
3715
    env->isolate()->RunMicrotasks();
1265
  }
1266
1267
5212
  Local<Object> process = env->process_object();
1268
1269
5212
  if (tick_info->length() == 0) {
1270
3709
    tick_info->set_index(0);
1271
3709
    return ret;
1272
  }
1273
1274
4509
  if (env->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
1275
3
    return Undefined(env->isolate());
1276
  }
1277
1278
1502
  return ret;
1279
}
1280
1281
1282
6244
Local<Value> MakeCallback(Environment* env,
1283
                           Local<Object> recv,
1284
                           Local<String> symbol,
1285
                           int argc,
1286
                           Local<Value> argv[]) {
1287
6244
  Local<Value> cb_v = recv->Get(symbol);
1288
6244
  CHECK(cb_v->IsFunction());
1289
12488
  return MakeCallback(env, recv.As<Value>(), cb_v.As<Function>(), argc, argv);
1290
}
1291
1292
1293
3115
Local<Value> MakeCallback(Environment* env,
1294
                           Local<Object> recv,
1295
                           const char* method,
1296
                           int argc,
1297
                           Local<Value> argv[]) {
1298
3115
  Local<String> method_string = OneByteString(env->isolate(), method);
1299
3115
  return MakeCallback(env, recv, method_string, argc, argv);
1300
}
1301
1302
1303
5
Local<Value> MakeCallback(Isolate* isolate,
1304
                          Local<Object> recv,
1305
                          const char* method,
1306
                          int argc,
1307
                          Local<Value> argv[]) {
1308
10
  EscapableHandleScope handle_scope(isolate);
1309
5
  Local<String> method_string = OneByteString(isolate, method);
1310
  return handle_scope.Escape(
1311
15
      MakeCallback(isolate, recv, method_string, argc, argv));
1312
}
1313
1314
1315
10
Local<Value> MakeCallback(Isolate* isolate,
1316
                          Local<Object> recv,
1317
                          Local<String> symbol,
1318
                          int argc,
1319
                          Local<Value> argv[]) {
1320
20
  EscapableHandleScope handle_scope(isolate);
1321
20
  Local<Value> callback_v = recv->Get(symbol);
1322
10
  if (callback_v.IsEmpty()) return Local<Value>();
1323
10
  if (!callback_v->IsFunction()) return Local<Value>();
1324
10
  Local<Function> callback = callback_v.As<Function>();
1325
10
  return handle_scope.Escape(MakeCallback(isolate, recv, callback, argc, argv));
1326
}
1327
1328
1329
32
Local<Value> MakeCallback(Isolate* isolate,
1330
                          Local<Object> recv,
1331
                          Local<Function> callback,
1332
                          int argc,
1333
                          Local<Value> argv[]) {
1334
  // Observe the following two subtleties:
1335
  //
1336
  // 1. The environment is retrieved from the callback function's context.
1337
  // 2. The context to enter is retrieved from the environment.
1338
  //
1339
  // Because of the AssignToContext() call in src/node_contextify.cc,
1340
  // the two contexts need not be the same.
1341
64
  EscapableHandleScope handle_scope(isolate);
1342
64
  Environment* env = Environment::GetCurrent(callback->CreationContext());
1343
96
  Context::Scope context_scope(env->context());
1344
  return handle_scope.Escape(
1345
96
      MakeCallback(env, recv.As<Value>(), callback, argc, argv));
1346
}
1347
1348
1349
54389
enum encoding ParseEncoding(const char* encoding,
1350
                            enum encoding default_encoding) {
1351

54389
  switch (encoding[0]) {
1352
    case 'u':
1353
      // utf8, utf16le
1354

4627
      if (encoding[1] == 't' && encoding[2] == 'f') {
1355
        // Skip `-`
1356
4436
        encoding += encoding[3] == '-' ? 4 : 3;
1357

4436
        if (encoding[0] == '8' && encoding[1] == '\0')
1358
          return UTF8;
1359
15
        if (strncmp(encoding, "16le", 4) == 0)
1360
          return UCS2;
1361
1362
      // ucs2
1363

191
      } else if (encoding[1] == 'c' && encoding[2] == 's') {
1364
190
        encoding += encoding[3] == '-' ? 4 : 3;
1365

190
        if (encoding[0] == '2' && encoding[1] == '\0')
1366
          return UCS2;
1367
      }
1368
      break;
1369
    case 'l':
1370
      // latin1
1371
46787
      if (encoding[1] == 'a') {
1372
46785
        if (strncmp(encoding + 2, "tin1", 4) == 0)
1373
          return LATIN1;
1374
      }
1375
      break;
1376
    case 'b':
1377
      // binary
1378
450
      if (encoding[1] == 'i') {
1379
30
        if (strncmp(encoding + 2, "nary", 4) == 0)
1380
          return LATIN1;
1381
1382
      // buffer
1383
420
      } else if (encoding[1] == 'u') {
1384
395
        if (strncmp(encoding + 2, "ffer", 4) == 0)
1385
          return BUFFER;
1386
      }
1387
      break;
1388
    case '\0':
1389
      return default_encoding;
1390
    default:
1391
      break;
1392
  }
1393
1394
2552
  if (StringEqualNoCase(encoding, "utf8")) {
1395
    return UTF8;
1396
2552
  } else if (StringEqualNoCase(encoding, "utf-8")) {
1397
    return UTF8;
1398
2551
  } else if (StringEqualNoCase(encoding, "ascii")) {
1399
    return ASCII;
1400
2504
  } else if (StringEqualNoCase(encoding, "base64")) {
1401
    return BASE64;
1402
2481
  } else if (StringEqualNoCase(encoding, "ucs2")) {
1403
    return UCS2;
1404
2481
  } else if (StringEqualNoCase(encoding, "ucs-2")) {
1405
    return UCS2;
1406
2481
  } else if (StringEqualNoCase(encoding, "utf16le")) {
1407
    return UCS2;
1408
2481
  } else if (StringEqualNoCase(encoding, "utf-16le")) {
1409
    return UCS2;
1410
2481
  } else if (StringEqualNoCase(encoding, "latin1")) {
1411
    return LATIN1;
1412
2481
  } else if (StringEqualNoCase(encoding, "binary")) {
1413
    return LATIN1;  // BINARY is a deprecated alias of LATIN1.
1414
2481
  } else if (StringEqualNoCase(encoding, "buffer")) {
1415
    return BUFFER;
1416
2481
  } else if (StringEqualNoCase(encoding, "hex")) {
1417
    return HEX;
1418
  } else {
1419
5
    return default_encoding;
1420
  }
1421
}
1422
1423
1424
56453
enum encoding ParseEncoding(Isolate* isolate,
1425
                            Local<Value> encoding_v,
1426
                            enum encoding default_encoding) {
1427
112906
  if (!encoding_v->IsString())
1428
    return default_encoding;
1429
1430
54389
  node::Utf8Value encoding(isolate, encoding_v);
1431
1432
54389
  return ParseEncoding(*encoding, default_encoding);
1433
}
1434
1435
193
Local<Value> Encode(Isolate* isolate,
1436
                    const char* buf,
1437
                    size_t len,
1438
                    enum encoding encoding) {
1439
193
  CHECK_NE(encoding, UCS2);
1440
193
  return StringBytes::Encode(isolate, buf, len, encoding);
1441
}
1442
1443
Local<Value> Encode(Isolate* isolate, const uint16_t* buf, size_t len) {
1444
  return StringBytes::Encode(isolate, buf, len);
1445
}
1446
1447
// Returns -1 if the handle was not valid for decoding
1448
ssize_t DecodeBytes(Isolate* isolate,
1449
                    Local<Value> val,
1450
                    enum encoding encoding) {
1451
  HandleScope scope(isolate);
1452
1453
  return StringBytes::Size(isolate, val, encoding);
1454
}
1455
1456
// Returns number of bytes written.
1457
ssize_t DecodeWrite(Isolate* isolate,
1458
                    char* buf,
1459
                    size_t buflen,
1460
                    Local<Value> val,
1461
                    enum encoding encoding) {
1462
  return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
1463
}
1464
1465
360
bool IsExceptionDecorated(Environment* env, Local<Value> er) {
1466

360
  if (!er.IsEmpty() && er->IsObject()) {
1467
360
    Local<Object> err_obj = er.As<Object>();
1468
    auto maybe_value =
1469
720
        err_obj->GetPrivate(env->context(), env->decorated_private_symbol());
1470
360
    Local<Value> decorated;
1471

360
    return maybe_value.ToLocal(&decorated) && decorated->IsTrue();
1472
  }
1473
  return false;
1474
}
1475
1476
360
void AppendExceptionLine(Environment* env,
1477
                         Local<Value> er,
1478
                         Local<Message> message,
1479
                         enum ErrorHandlingMode mode) {
1480
360
  if (message.IsEmpty())
1481
27
    return;
1482
1483
693
  HandleScope scope(env->isolate());
1484
360
  Local<Object> err_obj;
1485

360
  if (!er.IsEmpty() && er->IsObject()) {
1486
360
    err_obj = er.As<Object>();
1487
1488
360
    auto context = env->context();
1489
360
    auto processed_private_symbol = env->processed_private_symbol();
1490
    // Do it only once per message
1491
720
    if (err_obj->HasPrivate(context, processed_private_symbol).FromJust())
1492
15
      return;
1493
    err_obj->SetPrivate(
1494
        context,
1495
        processed_private_symbol,
1496
1035
        True(env->isolate()));
1497
  }
1498
1499
  // Print (filename):(line number): (message).
1500
678
  node::Utf8Value filename(env->isolate(), message->GetScriptResourceName());
1501
345
  const char* filename_string = *filename;
1502
345
  int linenum = message->GetLineNumber();
1503
  // Print line of source code.
1504
1023
  node::Utf8Value sourceline(env->isolate(), message->GetSourceLine());
1505
345
  const char* sourceline_string = *sourceline;
1506
1507
  // Because of how node modules work, all scripts are wrapped with a
1508
  // "function (module, exports, __filename, ...) {"
1509
  // to provide script local variables.
1510
  //
1511
  // When reporting errors on the first line of a script, this wrapper
1512
  // function is leaked to the user. There used to be a hack here to
1513
  // truncate off the first 62 characters, but it caused numerous other
1514
  // problems when vm.runIn*Context() methods were used for non-module
1515
  // code.
1516
  //
1517
  // If we ever decide to re-instate such a hack, the following steps
1518
  // must be taken:
1519
  //
1520
  // 1. Pass a flag around to say "this code was wrapped"
1521
  // 2. Update the stack frame output so that it is also correct.
1522
  //
1523
  // It would probably be simpler to add a line rather than add some
1524
  // number of characters to the first line, since V8 truncates the
1525
  // sourceline to 78 characters, and we end up not providing very much
1526
  // useful debugging info to the user if we remove 62 characters.
1527
1528
1035
  int start = message->GetStartColumn(env->context()).FromMaybe(0);
1529
1035
  int end = message->GetEndColumn(env->context()).FromMaybe(0);
1530
1531
  char arrow[1024];
1532
345
  int max_off = sizeof(arrow) - 2;
1533
1534
  int off = snprintf(arrow,
1535
                     sizeof(arrow),
1536
                     "%s:%i\n%s\n",
1537
                     filename_string,
1538
                     linenum,
1539
345
                     sourceline_string);
1540
345
  CHECK_GE(off, 0);
1541
345
  if (off > max_off) {
1542
138
    off = max_off;
1543
  }
1544
1545
  // Print wavy underline (GetUnderline is deprecated).
1546
12981
  for (int i = 0; i < start; i++) {
1547

6463
    if (sourceline_string[i] == '\0' || off >= max_off) {
1548
      break;
1549
    }
1550
6318
    CHECK_LT(off, max_off);
1551
6318
    arrow[off++] = (sourceline_string[i] == '\t') ? '\t' : ' ';
1552
  }
1553
1603
  for (int i = start; i < end; i++) {
1554

793
    if (sourceline_string[i] == '\0' || off >= max_off) {
1555
      break;
1556
    }
1557
629
    CHECK_LT(off, max_off);
1558
629
    arrow[off++] = '^';
1559
  }
1560
345
  CHECK_LE(off, max_off);
1561
345
  arrow[off] = '\n';
1562
345
  arrow[off + 1] = '\0';
1563
1564
345
  Local<String> arrow_str = String::NewFromUtf8(env->isolate(), arrow);
1565
1566

345
  const bool can_set_arrow = !arrow_str.IsEmpty() && !err_obj.IsEmpty();
1567
  // If allocating arrow_str failed, print it out. There's not much else to do.
1568
  // If it's not an error, but something needs to be printed out because
1569
  // it's a fatal exception, also print it out from here.
1570
  // Otherwise, the arrow property will be attached to the object and handled
1571
  // by the caller.
1572


345
  if (!can_set_arrow || (mode == FATAL_ERROR && !err_obj->IsNativeError())) {
1573
12
    if (env->printed_error())
1574
12
      return;
1575
12
    env->set_printed_error(true);
1576
1577
12
    uv_tty_reset_mode();
1578
12
    PrintErrorString("\n%s", arrow);
1579
12
    return;
1580
  }
1581
1582
1665
  CHECK(err_obj->SetPrivate(
1583
            env->context(),
1584
            env->arrow_message_private_symbol(),
1585
            arrow_str).FromMaybe(false));
1586
}
1587
1588
1589
59
static void ReportException(Environment* env,
1590
                            Local<Value> er,
1591
                            Local<Message> message) {
1592
118
  HandleScope scope(env->isolate());
1593
1594
59
  AppendExceptionLine(env, er, message, FATAL_ERROR);
1595
1596
59
  Local<Value> trace_value;
1597
59
  Local<Value> arrow;
1598
59
  const bool decorated = IsExceptionDecorated(env, er);
1599
1600

177
  if (er->IsUndefined() || er->IsNull()) {
1601
    trace_value = Undefined(env->isolate());
1602
  } else {
1603
59
    Local<Object> err_obj = er->ToObject(env->isolate());
1604
1605
118
    trace_value = err_obj->Get(env->stack_string());
1606
    arrow =
1607
59
        err_obj->GetPrivate(
1608
            env->context(),
1609
118
            env->arrow_message_private_symbol()).ToLocalChecked();
1610
  }
1611
1612
118
  node::Utf8Value trace(env->isolate(), trace_value);
1613
1614
  // range errors have a trace member set to undefined
1615

118
  if (trace.length() > 0 && !trace_value->IsUndefined()) {
1616


116
    if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
1617
26
      PrintErrorString("%s\n", *trace);
1618
    } else {
1619
64
      node::Utf8Value arrow_string(env->isolate(), arrow);
1620
32
      PrintErrorString("%s\n%s\n", *arrow_string, *trace);
1621
    }
1622
  } else {
1623
    // this really only happens for RangeErrors, since they're the only
1624
    // kind that won't have all this info in the trace, or when non-Error
1625
    // objects are thrown manually.
1626
1
    Local<Value> message;
1627
1
    Local<Value> name;
1628
1629
1
    if (er->IsObject()) {
1630
1
      Local<Object> err_obj = er.As<Object>();
1631
2
      message = err_obj->Get(env->message_string());
1632
2
      name = err_obj->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "name"));
1633
    }
1634
1635

3
    if (message.IsEmpty() ||
1636
2
        message->IsUndefined() ||
1637

1
        name.IsEmpty() ||
1638
        name->IsUndefined()) {
1639
      // Not an error object. Just print as-is.
1640
2
      String::Utf8Value message(er);
1641
1642
1
      PrintErrorString("%s\n", *message ? *message :
1643
1
                                          "<toString() threw exception>");
1644
    } else {
1645
      node::Utf8Value name_string(env->isolate(), name);
1646
      node::Utf8Value message_string(env->isolate(), message);
1647
1648
      if (arrow.IsEmpty() || !arrow->IsString() || decorated) {
1649
        PrintErrorString("%s: %s\n", *name_string, *message_string);
1650
      } else {
1651
        node::Utf8Value arrow_string(env->isolate(), arrow);
1652
        PrintErrorString("%s\n%s: %s\n",
1653
                         *arrow_string,
1654
                         *name_string,
1655
                         *message_string);
1656
      }
1657
    }
1658
  }
1659
1660
59
  fflush(stderr);
1661
59
}
1662
1663
1664
2
static void ReportException(Environment* env, const TryCatch& try_catch) {
1665
2
  ReportException(env, try_catch.Exception(), try_catch.Message());
1666
2
}
1667
1668
1669
// Executes a str within the current v8 context.
1670
1750
static Local<Value> ExecuteString(Environment* env,
1671
                                  Local<String> source,
1672
                                  Local<String> filename) {
1673
3500
  EscapableHandleScope scope(env->isolate());
1674
3500
  TryCatch try_catch(env->isolate());
1675
1676
  // try_catch must be nonverbose to disable FatalException() handler,
1677
  // we will handle exceptions ourself.
1678
1750
  try_catch.SetVerbose(false);
1679
1680
5250
  ScriptOrigin origin(filename);
1681
  MaybeLocal<v8::Script> script =
1682
1750
      v8::Script::Compile(env->context(), source, &origin);
1683
1750
  if (script.IsEmpty()) {
1684
    ReportException(env, try_catch);
1685
    exit(3);
1686
  }
1687
1688
1750
  Local<Value> result = script.ToLocalChecked()->Run();
1689
1750
  if (result.IsEmpty()) {
1690
    ReportException(env, try_catch);
1691
    exit(4);
1692
  }
1693
1694
3500
  return scope.Escape(result);
1695
}
1696
1697
1698
1
static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
1699
1
  Environment* env = Environment::GetCurrent(args);
1700
1701
1
  Local<Array> ary = Array::New(args.GetIsolate());
1702
1
  Local<Context> ctx = env->context();
1703
1
  Local<Function> fn = env->push_values_to_array_function();
1704
17
  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1705
1
  size_t idx = 0;
1706
1707
15
  for (auto w : *env->req_wrap_queue()) {
1708
24
    if (w->persistent().IsEmpty())
1709
      continue;
1710
36
    argv[idx] = w->object();
1711
12
    if (++idx >= arraysize(argv)) {
1712
3
      fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1713
1
      idx = 0;
1714
    }
1715
  }
1716
1717
1
  if (idx > 0) {
1718
3
    fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1719
  }
1720
1721
2
  args.GetReturnValue().Set(ary);
1722
1
}
1723
1724
1725
// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
1726
// implemented here for consistency with GetActiveRequests().
1727
3
void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
1728
3
  Environment* env = Environment::GetCurrent(args);
1729
1730
3
  Local<Array> ary = Array::New(env->isolate());
1731
3
  Local<Context> ctx = env->context();
1732
3
  Local<Function> fn = env->push_values_to_array_function();
1733
51
  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
1734
3
  size_t idx = 0;
1735
1736
3
  Local<String> owner_sym = env->owner_string();
1737
1738
29
  for (auto w : *env->handle_wrap_queue()) {
1739

40
    if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w))
1740
      continue;
1741
40
    Local<Object> object = w->object();
1742
20
    Local<Value> owner = object->Get(owner_sym);
1743
40
    if (owner->IsUndefined())
1744
3
      owner = object;
1745
20
    argv[idx] = owner;
1746
20
    if (++idx >= arraysize(argv)) {
1747
6
      fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1748
2
      idx = 0;
1749
    }
1750
  }
1751
3
  if (idx > 0) {
1752
6
    fn->Call(ctx, ary, idx, argv).ToLocalChecked();
1753
  }
1754
1755
6
  args.GetReturnValue().Set(ary);
1756
3
}
1757
1758
1759
NO_RETURN void Abort() {
1760
  DumpBacktrace(stderr);
1761
  fflush(stderr);
1762
  ABORT_NO_BACKTRACE();
1763
}
1764
1765
1766
NO_RETURN void Assert(const char* const (*args)[4]) {
1767
  auto filename = (*args)[0];
1768
  auto linenum = (*args)[1];
1769
  auto message = (*args)[2];
1770
  auto function = (*args)[3];
1771
1772
  char exepath[256];
1773
  size_t exepath_size = sizeof(exepath);
1774
  if (uv_exepath(exepath, &exepath_size))
1775
    snprintf(exepath, sizeof(exepath), "node");
1776
1777
  char pid[12] = {0};
1778
#ifndef _WIN32
1779
  snprintf(pid, sizeof(pid), "[%u]", getpid());
1780
#endif
1781
1782
  fprintf(stderr, "%s%s: %s:%s:%s%s Assertion `%s' failed.\n",
1783
          exepath, pid, filename, linenum,
1784
          function, *function ? ":" : "", message);
1785
  fflush(stderr);
1786
1787
  Abort();
1788
}
1789
1790
1791
static void Abort(const FunctionCallbackInfo<Value>& args) {
1792
  Abort();
1793
}
1794
1795
1796
46
static void Chdir(const FunctionCallbackInfo<Value>& args) {
1797
46
  Environment* env = Environment::GetCurrent(args);
1798
1799

180
  if (args.Length() != 1 || !args[0]->IsString()) {
1800
3
    return env->ThrowTypeError("Bad argument.");
1801
  }
1802
1803
129
  node::Utf8Value path(args.GetIsolate(), args[0]);
1804
43
  int err = uv_chdir(*path);
1805
43
  if (err) {
1806
    return env->ThrowUVException(err, "uv_chdir");
1807
  }
1808
}
1809
1810
1811
2132
static void Cwd(const FunctionCallbackInfo<Value>& args) {
1812
2132
  Environment* env = Environment::GetCurrent(args);
1813
#ifdef _WIN32
1814
  /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
1815
  char buf[MAX_PATH * 4];
1816
#else
1817
  char buf[PATH_MAX];
1818
#endif
1819
1820
2132
  size_t cwd_len = sizeof(buf);
1821
2132
  int err = uv_cwd(buf, &cwd_len);
1822
2132
  if (err) {
1823
4
    return env->ThrowUVException(err, "uv_cwd");
1824
  }
1825
1826
  Local<String> cwd = String::NewFromUtf8(env->isolate(),
1827
                                          buf,
1828
                                          String::kNormalString,
1829
2128
                                          cwd_len);
1830
4256
  args.GetReturnValue().Set(cwd);
1831
}
1832
1833
1834
138
static void Umask(const FunctionCallbackInfo<Value>& args) {
1835
138
  Environment* env = Environment::GetCurrent(args);
1836
  uint32_t old;
1837
1838

282
  if (args.Length() < 1 || args[0]->IsUndefined()) {
1839
135
    old = umask(0);
1840
135
    umask(static_cast<mode_t>(old));
1841

8
  } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
1842
    return env->ThrowTypeError("argument must be an integer or octal string.");
1843
  } else {
1844
    int oct;
1845
3
    if (args[0]->IsInt32()) {
1846
2
      oct = args[0]->Uint32Value();
1847
    } else {
1848
1
      oct = 0;
1849
2
      node::Utf8Value str(env->isolate(), args[0]);
1850
1851
      // Parse the octal string.
1852
5
      for (size_t i = 0; i < str.length(); i++) {
1853
4
        char c = (*str)[i];
1854
4
        if (c > '7' || c < '0') {
1855
          return env->ThrowTypeError("invalid octal string");
1856
        }
1857
4
        oct *= 8;
1858
4
        oct += c - '0';
1859
      }
1860
    }
1861
3
    old = umask(static_cast<mode_t>(oct));
1862
  }
1863
1864
138
  args.GetReturnValue().Set(old);
1865
}
1866
1867
1868
#if defined(__POSIX__) && !defined(__ANDROID__)
1869
1870
static const uid_t uid_not_found = static_cast<uid_t>(-1);
1871
static const gid_t gid_not_found = static_cast<gid_t>(-1);
1872
1873
1874
static uid_t uid_by_name(const char* name) {
1875
  struct passwd pwd;
1876
  struct passwd* pp;
1877
  char buf[8192];
1878
1879
  errno = 0;
1880
  pp = nullptr;
1881
1882
  if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
1883
    return pp->pw_uid;
1884
  }
1885
1886
  return uid_not_found;
1887
}
1888
1889
1890
static char* name_by_uid(uid_t uid) {
1891
  struct passwd pwd;
1892
  struct passwd* pp;
1893
  char buf[8192];
1894
  int rc;
1895
1896
  errno = 0;
1897
  pp = nullptr;
1898
1899
  if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1900
      pp != nullptr) {
1901
    return strdup(pp->pw_name);
1902
  }
1903
1904
  if (rc == 0) {
1905
    errno = ENOENT;
1906
  }
1907
1908
  return nullptr;
1909
}
1910
1911
1912
static gid_t gid_by_name(const char* name) {
1913
  struct group pwd;
1914
  struct group* pp;
1915
  char buf[8192];
1916
1917
  errno = 0;
1918
  pp = nullptr;
1919
1920
  if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr) {
1921
    return pp->gr_gid;
1922
  }
1923
1924
  return gid_not_found;
1925
}
1926
1927
1928
#if 0  // For future use.
1929
static const char* name_by_gid(gid_t gid) {
1930
  struct group pwd;
1931
  struct group* pp;
1932
  char buf[8192];
1933
  int rc;
1934
1935
  errno = 0;
1936
  pp = nullptr;
1937
1938
  if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
1939
      pp != nullptr) {
1940
    return strdup(pp->gr_name);
1941
  }
1942
1943
  if (rc == 0) {
1944
    errno = ENOENT;
1945
  }
1946
1947
  return nullptr;
1948
}
1949
#endif
1950
1951
1952
static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
1953
  if (value->IsUint32()) {
1954
    return static_cast<uid_t>(value->Uint32Value());
1955
  } else {
1956
    node::Utf8Value name(isolate, value);
1957
    return uid_by_name(*name);
1958
  }
1959
}
1960
1961
1962
static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
1963
  if (value->IsUint32()) {
1964
    return static_cast<gid_t>(value->Uint32Value());
1965
  } else {
1966
    node::Utf8Value name(isolate, value);
1967
    return gid_by_name(*name);
1968
  }
1969
}
1970
1971
18
static void GetUid(const FunctionCallbackInfo<Value>& args) {
1972
  // uid_t is an uint32_t on all supported platforms.
1973
54
  args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
1974
18
}
1975
1976
1977
7
static void GetGid(const FunctionCallbackInfo<Value>& args) {
1978
  // gid_t is an uint32_t on all supported platforms.
1979
21
  args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
1980
7
}
1981
1982
1983
static void GetEUid(const FunctionCallbackInfo<Value>& args) {
1984
  // uid_t is an uint32_t on all supported platforms.
1985
  args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
1986
}
1987
1988
1989
static void GetEGid(const FunctionCallbackInfo<Value>& args) {
1990
  // gid_t is an uint32_t on all supported platforms.
1991
  args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
1992
}
1993
1994
1995
static void SetGid(const FunctionCallbackInfo<Value>& args) {
1996
  Environment* env = Environment::GetCurrent(args);
1997
1998
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
1999
    return env->ThrowTypeError("setgid argument must be a number or a string");
2000
  }
2001
2002
  gid_t gid = gid_by_name(env->isolate(), args[0]);
2003
2004
  if (gid == gid_not_found) {
2005
    return env->ThrowError("setgid group id does not exist");
2006
  }
2007
2008
  if (setgid(gid)) {
2009
    return env->ThrowErrnoException(errno, "setgid");
2010
  }
2011
}
2012
2013
2014
static void SetEGid(const FunctionCallbackInfo<Value>& args) {
2015
  Environment* env = Environment::GetCurrent(args);
2016
2017
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2018
    return env->ThrowTypeError("setegid argument must be a number or string");
2019
  }
2020
2021
  gid_t gid = gid_by_name(env->isolate(), args[0]);
2022
2023
  if (gid == gid_not_found) {
2024
    return env->ThrowError("setegid group id does not exist");
2025
  }
2026
2027
  if (setegid(gid)) {
2028
    return env->ThrowErrnoException(errno, "setegid");
2029
  }
2030
}
2031
2032
2033
static void SetUid(const FunctionCallbackInfo<Value>& args) {
2034
  Environment* env = Environment::GetCurrent(args);
2035
2036
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2037
    return env->ThrowTypeError("setuid argument must be a number or a string");
2038
  }
2039
2040
  uid_t uid = uid_by_name(env->isolate(), args[0]);
2041
2042
  if (uid == uid_not_found) {
2043
    return env->ThrowError("setuid user id does not exist");
2044
  }
2045
2046
  if (setuid(uid)) {
2047
    return env->ThrowErrnoException(errno, "setuid");
2048
  }
2049
}
2050
2051
2052
static void SetEUid(const FunctionCallbackInfo<Value>& args) {
2053
  Environment* env = Environment::GetCurrent(args);
2054
2055
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2056
    return env->ThrowTypeError("seteuid argument must be a number or string");
2057
  }
2058
2059
  uid_t uid = uid_by_name(env->isolate(), args[0]);
2060
2061
  if (uid == uid_not_found) {
2062
    return env->ThrowError("seteuid user id does not exist");
2063
  }
2064
2065
  if (seteuid(uid)) {
2066
    return env->ThrowErrnoException(errno, "seteuid");
2067
  }
2068
}
2069
2070
2071
1
static void GetGroups(const FunctionCallbackInfo<Value>& args) {
2072
1
  Environment* env = Environment::GetCurrent(args);
2073
2074
1
  int ngroups = getgroups(0, nullptr);
2075
2076
1
  if (ngroups == -1) {
2077
    return env->ThrowErrnoException(errno, "getgroups");
2078
  }
2079
2080
1
  gid_t* groups = new gid_t[ngroups];
2081
2082
1
  ngroups = getgroups(ngroups, groups);
2083
2084
1
  if (ngroups == -1) {
2085
    delete[] groups;
2086
    return env->ThrowErrnoException(errno, "getgroups");
2087
  }
2088
2089
1
  Local<Array> groups_list = Array::New(env->isolate(), ngroups);
2090
1
  bool seen_egid = false;
2091
1
  gid_t egid = getegid();
2092
2093
2
  for (int i = 0; i < ngroups; i++) {
2094
2
    groups_list->Set(i, Integer::New(env->isolate(), groups[i]));
2095
1
    if (groups[i] == egid)
2096
1
      seen_egid = true;
2097
  }
2098
2099
1
  delete[] groups;
2100
2101
1
  if (seen_egid == false) {
2102
    groups_list->Set(ngroups, Integer::New(env->isolate(), egid));
2103
  }
2104
2105
1
  args.GetReturnValue().Set(groups_list);
2106
}
2107
2108
2109
static void SetGroups(const FunctionCallbackInfo<Value>& args) {
2110
  Environment* env = Environment::GetCurrent(args);
2111
2112
  if (!args[0]->IsArray()) {
2113
    return env->ThrowTypeError("argument 1 must be an array");
2114
  }
2115
2116
  Local<Array> groups_list = args[0].As<Array>();
2117
  size_t size = groups_list->Length();
2118
  gid_t* groups = new gid_t[size];
2119
2120
  for (size_t i = 0; i < size; i++) {
2121
    gid_t gid = gid_by_name(env->isolate(), groups_list->Get(i));
2122
2123
    if (gid == gid_not_found) {
2124
      delete[] groups;
2125
      return env->ThrowError("group name not found");
2126
    }
2127
2128
    groups[i] = gid;
2129
  }
2130
2131
  int rc = setgroups(size, groups);
2132
  delete[] groups;
2133
2134
  if (rc == -1) {
2135
    return env->ThrowErrnoException(errno, "setgroups");
2136
  }
2137
}
2138
2139
2140
static void InitGroups(const FunctionCallbackInfo<Value>& args) {
2141
  Environment* env = Environment::GetCurrent(args);
2142
2143
  if (!args[0]->IsUint32() && !args[0]->IsString()) {
2144
    return env->ThrowTypeError("argument 1 must be a number or a string");
2145
  }
2146
2147
  if (!args[1]->IsUint32() && !args[1]->IsString()) {
2148
    return env->ThrowTypeError("argument 2 must be a number or a string");
2149
  }
2150
2151
  node::Utf8Value arg0(env->isolate(), args[0]);
2152
  gid_t extra_group;
2153
  bool must_free;
2154
  char* user;
2155
2156
  if (args[0]->IsUint32()) {
2157
    user = name_by_uid(args[0]->Uint32Value());
2158
    must_free = true;
2159
  } else {
2160
    user = *arg0;
2161
    must_free = false;
2162
  }
2163
2164
  if (user == nullptr) {
2165
    return env->ThrowError("initgroups user not found");
2166
  }
2167
2168
  extra_group = gid_by_name(env->isolate(), args[1]);
2169
2170
  if (extra_group == gid_not_found) {
2171
    if (must_free)
2172
      free(user);
2173
    return env->ThrowError("initgroups extra group not found");
2174
  }
2175
2176
  int rc = initgroups(user, extra_group);
2177
2178
  if (must_free) {
2179
    free(user);
2180
  }
2181
2182
  if (rc) {
2183
    return env->ThrowErrnoException(errno, "initgroups");
2184
  }
2185
}
2186
2187
#endif  // __POSIX__ && !defined(__ANDROID__)
2188
2189
2190
1686
static void WaitForInspectorDisconnect(Environment* env) {
2191
#if HAVE_INSPECTOR
2192
1686
  if (env->inspector_agent()->IsConnected()) {
2193
    // Restore signal dispositions, the app is done and is no longer
2194
    // capable of handling signals.
2195
#ifdef __POSIX__
2196
    struct sigaction act;
2197
    memset(&act, 0, sizeof(act));
2198
    for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
2199
      if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
2200
        continue;
2201
      act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
2202
      CHECK_EQ(0, sigaction(nr, &act, nullptr));
2203
    }
2204
#endif
2205
    env->inspector_agent()->WaitForDisconnect();
2206
  }
2207
#endif
2208
1686
}
2209
2210
2211
141
void Exit(const FunctionCallbackInfo<Value>& args) {
2212
141
  WaitForInspectorDisconnect(Environment::GetCurrent(args));
2213
141
  exit(args[0]->Int32Value());
2214
}
2215
2216
2217
static void Uptime(const FunctionCallbackInfo<Value>& args) {
2218
  Environment* env = Environment::GetCurrent(args);
2219
  double uptime;
2220
2221
  uv_update_time(env->event_loop());
2222
  uptime = uv_now(env->event_loop()) - prog_start_time;
2223
2224
  args.GetReturnValue().Set(Number::New(env->isolate(), uptime / 1000));
2225
}
2226
2227
2228
2
void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
2229
2
  Environment* env = Environment::GetCurrent(args);
2230
2231
  size_t rss;
2232
2
  int err = uv_resident_set_memory(&rss);
2233
2
  if (err) {
2234
    return env->ThrowUVException(err, "uv_resident_set_memory");
2235
  }
2236
2237
  // V8 memory usage
2238
2
  HeapStatistics v8_heap_stats;
2239
2
  env->isolate()->GetHeapStatistics(&v8_heap_stats);
2240
2241
  Local<Number> heap_total =
2242
2
      Number::New(env->isolate(), v8_heap_stats.total_heap_size());
2243
  Local<Number> heap_used =
2244
2
      Number::New(env->isolate(), v8_heap_stats.used_heap_size());
2245
  Local<Number> external_mem =
2246
      Number::New(env->isolate(),
2247
4
                  env->isolate()->AdjustAmountOfExternalAllocatedMemory(0));
2248
2249
2
  Local<Object> info = Object::New(env->isolate());
2250
8
  info->Set(env->rss_string(), Number::New(env->isolate(), rss));
2251
6
  info->Set(env->heap_total_string(), heap_total);
2252
6
  info->Set(env->heap_used_string(), heap_used);
2253
6
  info->Set(env->external_string(), external_mem);
2254
2255
4
  args.GetReturnValue().Set(info);
2256
}
2257
2258
2259
44
void Kill(const FunctionCallbackInfo<Value>& args) {
2260
44
  Environment* env = Environment::GetCurrent(args);
2261
2262
44
  if (args.Length() != 2) {
2263
    return env->ThrowError("Bad argument.");
2264
  }
2265
2266
44
  int pid = args[0]->Int32Value();
2267
44
  int sig = args[1]->Int32Value();
2268
44
  int err = uv_kill(pid, sig);
2269
88
  args.GetReturnValue().Set(err);
2270
}
2271
2272
// used in Hrtime() below
2273
#define NANOS_PER_SEC 1000000000
2274
2275
// Hrtime exposes libuv's uv_hrtime() high-resolution timer.
2276
// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
2277
// so this function instead returns an Array with 2 entries representing seconds
2278
// and nanoseconds, to avoid any integer overflow possibility.
2279
// Pass in an Array from a previous hrtime() call to instead get a time diff.
2280
20
void Hrtime(const FunctionCallbackInfo<Value>& args) {
2281
20
  uint64_t t = uv_hrtime();
2282
2283
40
  Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
2284
20
  uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data());
2285
2286
  // These three indices will contain the values for the hrtime tuple. The
2287
  // seconds value is broken into the upper/lower 32 bits and stored in two
2288
  // uint32 fields to be converted back in JS.
2289
20
  fields[0] = (t / NANOS_PER_SEC) >> 32;
2290
20
  fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
2291
20
  fields[2] = t % NANOS_PER_SEC;
2292
20
}
2293
2294
// Microseconds in a second, as a float, used in CPUUsage() below
2295
#define MICROS_PER_SEC 1e6
2296
2297
// CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
2298
// to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
2299
// which are uv_timeval_t structs (long tv_sec, long tv_usec).
2300
// Returns those values as Float64 microseconds in the elements of the array
2301
// passed to the function.
2302
33
void CPUUsage(const FunctionCallbackInfo<Value>& args) {
2303
  uv_rusage_t rusage;
2304
2305
  // Call libuv to get the values we'll return.
2306
33
  int err = uv_getrusage(&rusage);
2307
33
  if (err) {
2308
    // On error, return the strerror version of the error code.
2309
    Local<String> errmsg = OneByteString(args.GetIsolate(), uv_strerror(err));
2310
    args.GetReturnValue().Set(errmsg);
2311
    return;
2312
  }
2313
2314
  // Get the double array pointer from the Float64Array argument.
2315
33
  CHECK(args[0]->IsFloat64Array());
2316
66
  Local<Float64Array> array = args[0].As<Float64Array>();
2317
33
  CHECK_EQ(array->Length(), 2);
2318
33
  Local<ArrayBuffer> ab = array->Buffer();
2319
33
  double* fields = static_cast<double*>(ab->GetContents().Data());
2320
2321
  // Set the Float64Array elements to be user / system values in microseconds.
2322
33
  fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
2323
33
  fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
2324
}
2325
2326
47471
extern "C" void node_module_register(void* m) {
2327
47471
  struct node_module* mp = reinterpret_cast<struct node_module*>(m);
2328
2329
47471
  if (mp->nm_flags & NM_F_BUILTIN) {
2330
47439
    mp->nm_link = modlist_builtin;
2331
47439
    modlist_builtin = mp;
2332
32
  } else if (!node_is_initialized) {
2333
    // "Linked" modules are included as part of the node project.
2334
    // Like builtins they are registered *before* node::Init runs.
2335
    mp->nm_flags = NM_F_LINKED;
2336
    mp->nm_link = modlist_linked;
2337
    modlist_linked = mp;
2338
  } else {
2339
32
    modpending = mp;
2340
  }
2341
47471
}
2342
2343
37176
struct node_module* get_builtin_module(const char* name) {
2344
  struct node_module* mp;
2345
2346
544098
  for (mp = modlist_builtin; mp != nullptr; mp = mp->nm_link) {
2347
540597
    if (strcmp(mp->nm_modname, name) == 0)
2348
      break;
2349
  }
2350
2351

37176
  CHECK(mp == nullptr || (mp->nm_flags & NM_F_BUILTIN) != 0);
2352
37176
  return (mp);
2353
}
2354
2355
struct node_module* get_linked_module(const char* name) {
2356
  struct node_module* mp;
2357
2358
  for (mp = modlist_linked; mp != nullptr; mp = mp->nm_link) {
2359
    if (strcmp(mp->nm_modname, name) == 0)
2360
      break;
2361
  }
2362
2363
  CHECK(mp == nullptr || (mp->nm_flags & NM_F_LINKED) != 0);
2364
  return mp;
2365
}
2366
2367
typedef void (UV_DYNAMIC* extInit)(Local<Object> exports);
2368
2369
// DLOpen is process.dlopen(module, filename).
2370
// Used to load 'module.node' dynamically shared objects.
2371
//
2372
// FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
2373
// when two contexts try to load the same shared object. Maybe have a shadow
2374
// cache that's a plain C list or hash table that's shared across contexts?
2375
35
void DLOpen(const FunctionCallbackInfo<Value>& args) {
2376
35
  Environment* env = Environment::GetCurrent(args);
2377
  uv_lib_t lib;
2378
2379
35
  CHECK_EQ(modpending, nullptr);
2380
2381
35
  if (args.Length() != 2) {
2382
    env->ThrowError("process.dlopen takes exactly 2 arguments.");
2383
4
    return;
2384
  }
2385
2386
70
  Local<Object> module = args[0]->ToObject(env->isolate());  // Cast
2387
66
  node::Utf8Value filename(env->isolate(), args[1]);  // Cast
2388
35
  const bool is_dlopen_error = uv_dlopen(*filename, &lib);
2389
2390
  // Objects containing v14 or later modules will have registered themselves
2391
  // on the pending list.  Activate all of them now.  At present, only one
2392
  // module per object is supported.
2393
35
  node_module* const mp = modpending;
2394
35
  modpending = nullptr;
2395
2396
35
  if (is_dlopen_error) {
2397
3
    Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib));
2398
3
    uv_dlclose(&lib);
2399
#ifdef _WIN32
2400
    // Windows needs to add the filename into the error message
2401
    errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate()));
2402
#endif  // _WIN32
2403
3
    env->isolate()->ThrowException(Exception::Error(errmsg));
2404
    return;
2405
  }
2406
2407
32
  if (mp == nullptr) {
2408
    uv_dlclose(&lib);
2409
    env->ThrowError("Module did not self-register.");
2410
    return;
2411
  }
2412
32
  if (mp->nm_version != NODE_MODULE_VERSION) {
2413
    char errmsg[1024];
2414
1
    snprintf(errmsg,
2415
             sizeof(errmsg),
2416
             "The module '%s'"
2417
             "\nwas compiled against a different Node.js version using"
2418
             "\nNODE_MODULE_VERSION %d. This version of Node.js requires"
2419
             "\nNODE_MODULE_VERSION %d. Please try re-compiling or "
2420
             "re-installing\nthe module (for instance, using `npm rebuild` or"
2421
             "`npm install`).",
2422
1
             *filename, mp->nm_version, NODE_MODULE_VERSION);
2423
2424
    // NOTE: `mp` is allocated inside of the shared library's memory, calling
2425
    // `uv_dlclose` will deallocate it
2426
1
    uv_dlclose(&lib);
2427
1
    env->ThrowError(errmsg);
2428
    return;
2429
  }
2430
31
  if (mp->nm_flags & NM_F_BUILTIN) {
2431
    uv_dlclose(&lib);
2432
    env->ThrowError("Built-in module self-registered.");
2433
    return;
2434
  }
2435
2436
31
  mp->nm_dso_handle = lib.handle;
2437
31
  mp->nm_link = modlist_addon;
2438
31
  modlist_addon = mp;
2439
2440
31
  Local<String> exports_string = env->exports_string();
2441
124
  Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate());
2442
2443
31
  if (mp->nm_context_register_func != nullptr) {
2444
6
    mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
2445
29
  } else if (mp->nm_register_func != nullptr) {
2446
58
    mp->nm_register_func(exports, module, mp->nm_priv);
2447
  } else {
2448
    uv_dlclose(&lib);
2449
    env->ThrowError("Module has no declared entry point.");
2450
    return;
2451
  }
2452
2453
  // Tell coverity that 'handle' should not be freed when we return.
2454
  // coverity[leaked_storage]
2455
}
2456
2457
2458
static void OnFatalError(const char* location, const char* message) {
2459
  if (location) {
2460
    PrintErrorString("FATAL ERROR: %s %s\n", location, message);
2461
  } else {
2462
    PrintErrorString("FATAL ERROR: %s\n", message);
2463
  }
2464
  fflush(stderr);
2465
  ABORT();
2466
}
2467
2468
2469
NO_RETURN void FatalError(const char* location, const char* message) {
2470
  OnFatalError(location, message);
2471
  // to suppress compiler warning
2472
  ABORT();
2473
}
2474
2475
2476
1175
void FatalException(Isolate* isolate,
2477
                    Local<Value> error,
2478
                    Local<Message> message) {
2479
2288
  HandleScope scope(isolate);
2480
2481
1175
  Environment* env = Environment::GetCurrent(isolate);
2482
1175
  Local<Object> process_object = env->process_object();
2483
1175
  Local<String> fatal_exception_string = env->fatal_exception_string();
2484
  Local<Function> fatal_exception_function =
2485
2350
      process_object->Get(fatal_exception_string).As<Function>();
2486
2487
1175
  int exit_code = 0;
2488
1175
  if (!fatal_exception_function->IsFunction()) {
2489
    // failed before the process._fatalException function was added!
2490
    // this is probably pretty bad.  Nothing to do but report and exit.
2491
    ReportException(env, error, message);
2492
    exit_code = 6;
2493
  }
2494
2495
1175
  if (exit_code == 0) {
2496
2347
    TryCatch fatal_try_catch(isolate);
2497
2498
    // Do not call FatalException when _fatalException handler throws
2499
1175
    fatal_try_catch.SetVerbose(false);
2500
2501
    // this will return true if the JS layer handled it, false otherwise
2502
    Local<Value> caught =
2503
1175
        fatal_exception_function->Call(process_object, 1, &error);
2504
2505
1172
    if (fatal_try_catch.HasCaught()) {
2506
      // the fatal exception function threw, so we must exit
2507
2
      ReportException(env, fatal_try_catch);
2508
2
      exit_code = 7;
2509
    }
2510
2511

2342
    if (exit_code == 0 && false == caught->BooleanValue()) {
2512
57
      ReportException(env, error, message);
2513
57
      exit_code = 1;
2514
    }
2515
  }
2516
2517
1172
  if (exit_code) {
2518
#if HAVE_INSPECTOR
2519
59
    if (debug_options.inspector_enabled()) {
2520
      env->inspector_agent()->FatalException(error, message);
2521
    }
2522
#endif
2523
59
    exit(exit_code);
2524
  }
2525
1113
}
2526
2527
2528
4
void FatalException(Isolate* isolate, const TryCatch& try_catch) {
2529
4
  HandleScope scope(isolate);
2530
  // TODO(bajtos) do not call FatalException if try_catch is verbose
2531
  // (requires V8 API to expose getter for try_catch.is_verbose_)
2532
4
  FatalException(isolate, try_catch.Exception(), try_catch.Message());
2533
}
2534
2535
2536
1171
void OnMessage(Local<Message> message, Local<Value> error) {
2537
  // The current version of V8 sends messages for errors only
2538
  // (thus `error` is always set).
2539
1171
  FatalException(Isolate::GetCurrent(), error, message);
2540
1113
}
2541
2542
2543
4
void ClearFatalExceptionHandlers(Environment* env) {
2544
4
  Local<Object> process = env->process_object();
2545
  Local<Value> events =
2546
16
      process->Get(env->context(), env->events_string()).ToLocalChecked();
2547
2548
4
  if (events->IsObject()) {
2549
12
    events.As<Object>()->Set(
2550
        env->context(),
2551
        OneByteString(env->isolate(), "uncaughtException"),
2552
32
        Undefined(env->isolate())).FromJust();
2553
  }
2554
2555
8
  process->Set(
2556
      env->context(),
2557
      env->domain_string(),
2558
32
      Undefined(env->isolate())).FromJust();
2559
4
}
2560
2561
// Call process.emitWarning(str), fmt is a snprintf() format string
2562
1
void ProcessEmitWarning(Environment* env, const char* fmt, ...) {
2563
  char warning[1024];
2564
  va_list ap;
2565
2566
1
  va_start(ap, fmt);
2567
1
  vsnprintf(warning, sizeof(warning), fmt, ap);
2568
1
  va_end(ap);
2569
2570
2
  HandleScope handle_scope(env->isolate());
2571
3
  Context::Scope context_scope(env->context());
2572
2573
1
  Local<Object> process = env->process_object();
2574
  MaybeLocal<Value> emit_warning = process->Get(env->context(),
2575
3
      FIXED_ONE_BYTE_STRING(env->isolate(), "emitWarning"));
2576
2
  Local<Value> arg = node::OneByteString(env->isolate(), warning);
2577
2578
1
  Local<Value> f;
2579
2580
1
  if (!emit_warning.ToLocal(&f)) return;
2581
1
  if (!f->IsFunction()) return;
2582
2583
  // MakeCallback() unneeded, because emitWarning is internal code, it calls
2584
  // process.emit('warning', ..), but does so on the nextTick.
2585
2
  f.As<v8::Function>()->Call(process, 1, &arg);
2586
}
2587
2588
2589
98142
static void Binding(const FunctionCallbackInfo<Value>& args) {
2590
98142
  Environment* env = Environment::GetCurrent(args);
2591
2592
196284
  Local<String> module = args[0]->ToString(env->isolate());
2593
133567
  node::Utf8Value module_v(env->isolate(), module);
2594
2595
98142
  Local<Object> cache = env->binding_cache_object();
2596
98142
  Local<Object> exports;
2597
2598
294426
  if (cache->Has(env->context(), module).FromJust()) {
2599
188148
    exports = cache->Get(module)->ToObject(env->isolate());
2600
62716
    args.GetReturnValue().Set(exports);
2601
62717
    return;
2602
  }
2603
2604
  // Append a string to process.moduleLoadList
2605
  char buf[1024];
2606
70852
  snprintf(buf, sizeof(buf), "Binding %s", *module_v);
2607
2608
35426
  Local<Array> modules = env->module_load_list_array();
2609
35426
  uint32_t l = modules->Length();
2610
70852
  modules->Set(l, OneByteString(env->isolate(), buf));
2611
2612
35426
  node_module* mod = get_builtin_module(*module_v);
2613
35426
  if (mod != nullptr) {
2614
31925
    exports = Object::New(env->isolate());
2615
    // Internal bindings don't have a "module" object, only exports.
2616
31925
    CHECK_EQ(mod->nm_register_func, nullptr);
2617
31925
    CHECK_NE(mod->nm_context_register_func, nullptr);
2618
95775
    Local<Value> unused = Undefined(env->isolate());
2619
63850
    mod->nm_context_register_func(exports, unused,
2620
31925
      env->context(), mod->nm_priv);
2621
63850
    cache->Set(module, exports);
2622
3501
  } else if (!strcmp(*module_v, "constants")) {
2623
1750
    exports = Object::New(env->isolate());
2624
1750
    DefineConstants(env->isolate(), exports);
2625
3500
    cache->Set(module, exports);
2626
1751
  } else if (!strcmp(*module_v, "natives")) {
2627
1750
    exports = Object::New(env->isolate());
2628
1750
    DefineJavaScript(env, exports);
2629
3500
    cache->Set(module, exports);
2630
  } else {
2631
    char errmsg[1024];
2632
1
    snprintf(errmsg,
2633
             sizeof(errmsg),
2634
             "No such module: %s",
2635
1
             *module_v);
2636
1
    return env->ThrowError(errmsg);
2637
  }
2638
2639
70850
  args.GetReturnValue().Set(exports);
2640
}
2641
2642
static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
2643
  Environment* env = Environment::GetCurrent(args.GetIsolate());
2644
2645
  Local<String> module_name = args[0]->ToString(env->isolate());
2646
2647
  Local<Object> cache = env->binding_cache_object();
2648
  Local<Value> exports_v = cache->Get(module_name);
2649
2650
  if (exports_v->IsObject())
2651
    return args.GetReturnValue().Set(exports_v.As<Object>());
2652
2653
  node::Utf8Value module_name_v(env->isolate(), module_name);
2654
  node_module* mod = get_linked_module(*module_name_v);
2655
2656
  if (mod == nullptr) {
2657
    char errmsg[1024];
2658
    snprintf(errmsg,
2659
             sizeof(errmsg),
2660
             "No such module was linked: %s",
2661
             *module_name_v);
2662
    return env->ThrowError(errmsg);
2663
  }
2664
2665
  Local<Object> module = Object::New(env->isolate());
2666
  Local<Object> exports = Object::New(env->isolate());
2667
  Local<String> exports_prop = String::NewFromUtf8(env->isolate(), "exports");
2668
  module->Set(exports_prop, exports);
2669
2670
  if (mod->nm_context_register_func != nullptr) {
2671
    mod->nm_context_register_func(exports,
2672
                                  module,
2673
                                  env->context(),
2674
                                  mod->nm_priv);
2675
  } else if (mod->nm_register_func != nullptr) {
2676
    mod->nm_register_func(exports, module, mod->nm_priv);
2677
  } else {
2678
    return env->ThrowError("Linked module has no declared entry point.");
2679
  }
2680
2681
  auto effective_exports = module->Get(exports_prop);
2682
  cache->Set(module_name, effective_exports);
2683
2684
  args.GetReturnValue().Set(effective_exports);
2685
}
2686
2687
4
static void ProcessTitleGetter(Local<Name> property,
2688
                               const PropertyCallbackInfo<Value>& info) {
2689
  char buffer[512];
2690
4
  uv_get_process_title(buffer, sizeof(buffer));
2691
12
  info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), buffer));
2692
4
}
2693
2694
2695
27
static void ProcessTitleSetter(Local<Name> property,
2696
                               Local<Value> value,
2697
                               const PropertyCallbackInfo<void>& info) {
2698
54
  node::Utf8Value title(info.GetIsolate(), value);
2699
  // TODO(piscisaureus): protect with a lock
2700
27
  uv_set_process_title(*title);
2701
27
}
2702
2703
2704
32757
static void EnvGetter(Local<Name> property,
2705
                      const PropertyCallbackInfo<Value>& info) {
2706
32757
  Isolate* isolate = info.GetIsolate();
2707
32757
  if (property->IsSymbol()) {
2708
19775
    return info.GetReturnValue().SetUndefined();
2709
  }
2710
#ifdef __POSIX__
2711
45743
  node::Utf8Value key(isolate, property);
2712
32753
  const char* val = getenv(*key);
2713
32753
  if (val) {
2714
59289
    return info.GetReturnValue().Set(String::NewFromUtf8(isolate, val));
2715
  }
2716
#else  // _WIN32
2717
  node::TwoByteValue key(isolate, property);
2718
  WCHAR buffer[32767];  // The maximum size allowed for environment variables.
2719
  DWORD result = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(*key),
2720
                                         buffer,
2721
                                         arraysize(buffer));
2722
  // If result >= sizeof buffer the buffer was too small. That should never
2723
  // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
2724
  // not found.
2725
  if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
2726
      result < arraysize(buffer)) {
2727
    const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
2728
    Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer);
2729
    return info.GetReturnValue().Set(rc);
2730
  }
2731
#endif
2732
}
2733
2734
2735
98
static void EnvSetter(Local<Name> property,
2736
                      Local<Value> value,
2737
                      const PropertyCallbackInfo<Value>& info) {
2738
#ifdef __POSIX__
2739
294
  node::Utf8Value key(info.GetIsolate(), property);
2740
196
  node::Utf8Value val(info.GetIsolate(), value);
2741
98
  setenv(*key, *val, 1);
2742
#else  // _WIN32
2743
  node::TwoByteValue key(info.GetIsolate(), property);
2744
  node::TwoByteValue val(info.GetIsolate(), value);
2745
  WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2746
  // Environment variables that start with '=' are read-only.
2747
  if (key_ptr[0] != L'=') {
2748
    SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
2749
  }
2750
#endif
2751
  // Whether it worked or not, always return value.
2752
196
  info.GetReturnValue().Set(value);
2753
98
}
2754
2755
2756
11254
static void EnvQuery(Local<Name> property,
2757
                     const PropertyCallbackInfo<Integer>& info) {
2758
11254
  int32_t rc = -1;  // Not found unless proven otherwise.
2759
#ifdef __POSIX__
2760
33762
  node::Utf8Value key(info.GetIsolate(), property);
2761
11254
  if (getenv(*key))
2762
10753
    rc = 0;
2763
#else  // _WIN32
2764
  node::TwoByteValue key(info.GetIsolate(), property);
2765
  WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2766
  if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
2767
      GetLastError() == ERROR_SUCCESS) {
2768
    rc = 0;
2769
    if (key_ptr[0] == L'=') {
2770
      // Environment variables that start with '=' are hidden and read-only.
2771
      rc = static_cast<int32_t>(v8::ReadOnly) |
2772
           static_cast<int32_t>(v8::DontDelete) |
2773
           static_cast<int32_t>(v8::DontEnum);
2774
    }
2775
  }
2776
#endif
2777
11254
  if (rc != -1)
2778
21506
    info.GetReturnValue().Set(rc);
2779
11254
}
2780
2781
2782
282
static void EnvDeleter(Local<Name> property,
2783
                       const PropertyCallbackInfo<Boolean>& info) {
2784
#ifdef __POSIX__
2785
846
  node::Utf8Value key(info.GetIsolate(), property);
2786
282
  unsetenv(*key);
2787
#else
2788
  node::TwoByteValue key(info.GetIsolate(), property);
2789
  WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
2790
  SetEnvironmentVariableW(key_ptr, nullptr);
2791
#endif
2792
2793
  // process.env never has non-configurable properties, so always
2794
  // return true like the tc39 delete operator.
2795
564
  info.GetReturnValue().Set(true);
2796
282
}
2797
2798
2799
908
static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
2800
908
  Environment* env = Environment::GetCurrent(info);
2801
908
  Isolate* isolate = env->isolate();
2802
908
  Local<Context> ctx = env->context();
2803
908
  Local<Function> fn = env->push_values_to_array_function();
2804
15436
  Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
2805
  size_t idx = 0;
2806
2807
#ifdef __POSIX__
2808
  int size = 0;
2809
27032
  while (environ[size])
2810
13062
    size++;
2811
2812
908
  Local<Array> envarr = Array::New(isolate);
2813
2814
13970
  for (int i = 0; i < size; ++i) {
2815
13062
    const char* var = environ[i];
2816
13062
    const char* s = strchr(var, '=');
2817
13062
    const int length = s ? s - var : strlen(var);
2818
    argv[idx] = String::NewFromUtf8(isolate,
2819
                                    var,
2820
                                    String::kNormalString,
2821
26124
                                    length);
2822
13062
    if (++idx >= arraysize(argv)) {
2823
3060
      fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2824
1020
      idx = 0;
2825
    }
2826
  }
2827
908
  if (idx > 0) {
2828
2538
    fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2829
  }
2830
#else  // _WIN32
2831
  WCHAR* environment = GetEnvironmentStringsW();
2832
  if (environment == nullptr)
2833
    return;  // This should not happen.
2834
  Local<Array> envarr = Array::New(isolate);
2835
  WCHAR* p = environment;
2836
  while (*p) {
2837
    WCHAR *s;
2838
    if (*p == L'=') {
2839
      // If the key starts with '=' it is a hidden environment variable.
2840
      p += wcslen(p) + 1;
2841
      continue;
2842
    } else {
2843
      s = wcschr(p, L'=');
2844
    }
2845
    if (!s) {
2846
      s = p + wcslen(p);
2847
    }
2848
    const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
2849
    const size_t two_byte_buffer_len = s - p;
2850
    argv[idx] = String::NewFromTwoByte(isolate,
2851
                                       two_byte_buffer,
2852
                                       String::kNormalString,
2853
                                       two_byte_buffer_len);
2854
    if (++idx >= arraysize(argv)) {
2855
      fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2856
      idx = 0;
2857
    }
2858
    p = s + wcslen(s) + 1;
2859
  }
2860
  if (idx > 0) {
2861
    fn->Call(ctx, envarr, idx, argv).ToLocalChecked();
2862
  }
2863
  FreeEnvironmentStringsW(environment);
2864
#endif
2865
2866
1816
  info.GetReturnValue().Set(envarr);
2867
908
}
2868
2869
2870
1750
static Local<Object> GetFeatures(Environment* env) {
2871
3500
  EscapableHandleScope scope(env->isolate());
2872
2873
1750
  Local<Object> obj = Object::New(env->isolate());
2874
#if defined(DEBUG) && DEBUG
2875
  Local<Value> debug = True(env->isolate());
2876
#else
2877
5250
  Local<Value> debug = False(env->isolate());
2878
#endif  // defined(DEBUG) && DEBUG
2879
2880
3500
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "debug"), debug);
2881
7000
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "uv"), True(env->isolate()));
2882
  // TODO(bnoordhuis) ping libuv
2883
7000
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate()));
2884
2885
#ifdef OPENSSL_NPN_NEGOTIATED
2886
3500
  Local<Boolean> tls_npn = True(env->isolate());
2887
#else
2888
  Local<Boolean> tls_npn = False(env->isolate());
2889
#endif
2890
3500
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_npn"), tls_npn);
2891
2892
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2893
3500
  Local<Boolean> tls_alpn = True(env->isolate());
2894
#else
2895
  Local<Boolean> tls_alpn = False(env->isolate());
2896
#endif
2897
3500
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_alpn"), tls_alpn);
2898
2899
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
2900
3500
  Local<Boolean> tls_sni = True(env->isolate());
2901
#else
2902
  Local<Boolean> tls_sni = False(env->isolate());
2903
#endif
2904
3500
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_sni"), tls_sni);
2905
2906
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2907
3500
  Local<Boolean> tls_ocsp = True(env->isolate());
2908
#else
2909
  Local<Boolean> tls_ocsp = False(env->isolate());
2910
#endif  // !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_set_tlsext_status_cb)
2911
3500
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_ocsp"), tls_ocsp);
2912
2913
8750
  obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls"),
2914
           Boolean::New(env->isolate(),
2915
3500
                        get_builtin_module("crypto") != nullptr));
2916
2917
3500
  return scope.Escape(obj);
2918
}
2919
2920
2921
42
static void DebugPortGetter(Local<Name> property,
2922
                            const PropertyCallbackInfo<Value>& info) {
2923
126
  info.GetReturnValue().Set(debug_options.port());
2924
42
}
2925
2926
2927
static void DebugPortSetter(Local<Name> property,
2928
                            Local<Value> value,
2929
                            const PropertyCallbackInfo<void>& info) {
2930
  debug_options.set_port(value->Int32Value());
2931
}
2932
2933
2934
static void DebugProcess(const FunctionCallbackInfo<Value>& args);
2935
static void DebugPause(const FunctionCallbackInfo<Value>& args);
2936
static void DebugEnd(const FunctionCallbackInfo<Value>& args);
2937
2938
2939
5388
void NeedImmediateCallbackGetter(Local<Name> property,
2940
                                 const PropertyCallbackInfo<Value>& info) {
2941
5388
  Environment* env = Environment::GetCurrent(info);
2942
5388
  const uv_check_t* immediate_check_handle = env->immediate_check_handle();
2943
5388
  bool active = uv_is_active(
2944
5388
      reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
2945
16164
  info.GetReturnValue().Set(active);
2946
5388
}
2947
2948
2949
3538
static void NeedImmediateCallbackSetter(
2950
    Local<Name> property,
2951
    Local<Value> value,
2952
    const PropertyCallbackInfo<void>& info) {
2953
3538
  Environment* env = Environment::GetCurrent(info);
2954
2955
3538
  uv_check_t* immediate_check_handle = env->immediate_check_handle();
2956
3538
  bool active = uv_is_active(
2957
3538
      reinterpret_cast<const uv_handle_t*>(immediate_check_handle));
2958
2959
3538
  if (active == value->BooleanValue())
2960
    return;
2961
2962
3515
  uv_idle_t* immediate_idle_handle = env->immediate_idle_handle();
2963
2964
3515
  if (active) {
2965
1747
    uv_check_stop(immediate_check_handle);
2966
1747
    uv_idle_stop(immediate_idle_handle);
2967
  } else {
2968
1768
    uv_check_start(immediate_check_handle, CheckImmediate);
2969
    // Idle handle is needed only to stop the event loop from blocking in poll.
2970
1768
    uv_idle_start(immediate_idle_handle, IdleImmediateDummy);
2971
  }
2972
}
2973
2974
2975
void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
2976
  Environment* env = Environment::GetCurrent(args);
2977
  env->StartProfilerIdleNotifier();
2978
}
2979
2980
2981
void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
2982
  Environment* env = Environment::GetCurrent(args);
2983
  env->StopProfilerIdleNotifier();
2984
}
2985
2986
2987
#define READONLY_PROPERTY(obj, str, var)                                      \
2988
  do {                                                                        \
2989
    obj->DefineOwnProperty(env->context(),                                    \
2990
                           OneByteString(env->isolate(), str),                \
2991
                           var,                                               \
2992
                           v8::ReadOnly).FromJust();                          \
2993
  } while (0)
2994
2995
#define READONLY_DONT_ENUM_PROPERTY(obj, str, var)                            \
2996
  do {                                                                        \
2997
    obj->DefineOwnProperty(env->context(),                                    \
2998
                           OneByteString(env->isolate(), str),                \
2999
                           var,                                               \
3000
                           static_cast<v8::PropertyAttribute>(v8::ReadOnly |  \
3001
                                                              v8::DontEnum))  \
3002
        .FromJust();                                                          \
3003
  } while (0)
3004
3005
3006
1750
void SetupProcessObject(Environment* env,
3007
                        int argc,
3008
                        const char* const* argv,
3009
                        int exec_argc,
3010
                        const char* const* exec_argv) {
3011
3500
  HandleScope scope(env->isolate());
3012
3013
1750
  Local<Object> process = env->process_object();
3014
3015
1750
  auto title_string = FIXED_ONE_BYTE_STRING(env->isolate(), "title");
3016
8750
  CHECK(process->SetAccessor(env->context(),
3017
                             title_string,
3018
                             ProcessTitleGetter,
3019
                             ProcessTitleSetter,
3020
                             env->as_external()).FromJust());
3021
3022
  // process.version
3023
8750
  READONLY_PROPERTY(process,
3024
                    "version",
3025
                    FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
3026
3027
  // process.moduleLoadList
3028
8750
  READONLY_PROPERTY(process,
3029
                    "moduleLoadList",
3030
                    env->module_load_list_array());
3031
3032
  // process.versions
3033
1750
  Local<Object> versions = Object::New(env->isolate());
3034
7000
  READONLY_PROPERTY(process, "versions", versions);
3035
3036
  const char http_parser_version[] = NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
3037
                                     "."
3038
                                     NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
3039
                                     "."
3040
1750
                                     NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
3041
8750
  READONLY_PROPERTY(versions,
3042
                    "http_parser",
3043
                    FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
3044
3045
  // +1 to get rid of the leading 'v'
3046
8750
  READONLY_PROPERTY(versions,
3047
                    "node",
3048
                    OneByteString(env->isolate(), NODE_VERSION + 1));
3049
8750
  READONLY_PROPERTY(versions,
3050
                    "v8",
3051
                    OneByteString(env->isolate(), V8::GetVersion()));
3052
8750
  READONLY_PROPERTY(versions,
3053
                    "uv",
3054
                    OneByteString(env->isolate(), uv_version_string()));
3055
8750
  READONLY_PROPERTY(versions,
3056
                    "zlib",
3057
                    FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
3058
8750
  READONLY_PROPERTY(versions,
3059
                    "ares",
3060
                    FIXED_ONE_BYTE_STRING(env->isolate(), ARES_VERSION_STR));
3061
3062
#if defined(NODE_HAVE_I18N_SUPPORT) && defined(U_ICU_VERSION)
3063
  // ICU-related versions are now handled on the js side, see bootstrap_node.js
3064
3065
1750
  if (icu_data_dir != nullptr) {
3066
    // Did the user attempt (via env var or parameter) to set an ICU path?
3067
    READONLY_PROPERTY(process,
3068
                      "icu_data_dir",
3069
                      OneByteString(env->isolate(), icu_data_dir));
3070
  }
3071
#endif
3072
3073
1750
  const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
3074
8750
  READONLY_PROPERTY(
3075
      versions,
3076
      "modules",
3077
      FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
3078
3079
  // process._promiseRejectEvent
3080
1750
  Local<Object> promiseRejectEvent = Object::New(env->isolate());
3081
7000
  READONLY_DONT_ENUM_PROPERTY(process,
3082
                              "_promiseRejectEvent",
3083
                              promiseRejectEvent);
3084
8750
  READONLY_PROPERTY(promiseRejectEvent,
3085
                    "unhandled",
3086
                    Integer::New(env->isolate(),
3087
                                 v8::kPromiseRejectWithNoHandler));
3088
8750
  READONLY_PROPERTY(promiseRejectEvent,
3089
                    "handled",
3090
                    Integer::New(env->isolate(),
3091
                                 v8::kPromiseHandlerAddedAfterReject));
3092
3093
#if HAVE_OPENSSL
3094
  // Stupid code to slice out the version string.
3095
  {  // NOLINT(whitespace/braces)
3096
    size_t i, j, k;
3097
    int c;
3098
15750
    for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
3099
15750
      c = OPENSSL_VERSION_TEXT[i];
3100
15750
      if ('0' <= c && c <= '9') {
3101
10500
        for (j = i + 1; j < k; ++j) {
3102
10500
          c = OPENSSL_VERSION_TEXT[j];
3103
10500
          if (c == ' ')
3104
            break;
3105
        }
3106
        break;
3107
      }
3108
    }
3109
8750
    READONLY_PROPERTY(
3110
        versions,
3111
        "openssl",
3112
        OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
3113
  }
3114
#endif
3115
3116
  // process.arch
3117
8750
  READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), NODE_ARCH));
3118
3119
  // process.platform
3120
8750
  READONLY_PROPERTY(process,
3121
                    "platform",
3122
                    OneByteString(env->isolate(), NODE_PLATFORM));
3123
3124
  // process.release
3125
1750
  Local<Object> release = Object::New(env->isolate());
3126
7000
  READONLY_PROPERTY(process, "release", release);
3127
8750
  READONLY_PROPERTY(release, "name", OneByteString(env->isolate(), "node"));
3128
3129
// if this is a release build and no explicit base has been set
3130
// substitute the standard release download URL
3131
#ifndef NODE_RELEASE_URLBASE
3132
# if NODE_VERSION_IS_RELEASE
3133
#  define NODE_RELEASE_URLBASE "https://nodejs.org/download/release/"
3134
# endif
3135
#endif
3136
3137
#if defined(NODE_RELEASE_URLBASE)
3138
#  define NODE_RELEASE_URLPFX NODE_RELEASE_URLBASE "v" NODE_VERSION_STRING "/"
3139
#  define NODE_RELEASE_URLFPFX NODE_RELEASE_URLPFX "node-v" NODE_VERSION_STRING
3140
3141
  READONLY_PROPERTY(release,
3142
                    "sourceUrl",
3143
                    OneByteString(env->isolate(),
3144
                    NODE_RELEASE_URLFPFX ".tar.gz"));
3145
  READONLY_PROPERTY(release,
3146
                    "headersUrl",
3147
                    OneByteString(env->isolate(),
3148
                    NODE_RELEASE_URLFPFX "-headers.tar.gz"));
3149
#  ifdef _WIN32
3150
  READONLY_PROPERTY(release,
3151
                    "libUrl",
3152
                    OneByteString(env->isolate(),
3153
                    strcmp(NODE_ARCH, "ia32") ? NODE_RELEASE_URLPFX "win-"
3154
                                                NODE_ARCH "/node.lib"
3155
                                              : NODE_RELEASE_URLPFX
3156
                                                "win-x86/node.lib"));
3157
#  endif
3158
#endif
3159
3160
  // process.argv
3161
1750
  Local<Array> arguments = Array::New(env->isolate(), argc);
3162
5499
  for (int i = 0; i < argc; ++i) {
3163
11247
    arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
3164
  }
3165
3500
  process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments);
3166
3167
  // process.execArgv
3168
1750
  Local<Array> exec_arguments = Array::New(env->isolate(), exec_argc);
3169
2072
  for (int i = 0; i < exec_argc; ++i) {
3170
966
    exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
3171
  }
3172
5250
  process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execArgv"),
3173
1750
               exec_arguments);
3174
3175
  // create process.env
3176
  Local<ObjectTemplate> process_env_template =
3177
1750
      ObjectTemplate::New(env->isolate());
3178
7000
  process_env_template->SetHandler(NamedPropertyHandlerConfiguration(
3179
          EnvGetter,
3180
          EnvSetter,
3181
          EnvQuery,
3182
          EnvDeleter,
3183
          EnvEnumerator,
3184
1750
          env->as_external()));
3185
3186
  Local<Object> process_env =
3187
3500
      process_env_template->NewInstance(env->context()).ToLocalChecked();
3188
3500
  process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "env"), process_env);
3189
3190
8750
  READONLY_PROPERTY(process, "pid", Integer::New(env->isolate(), getpid()));
3191
8750
  READONLY_PROPERTY(process, "features", GetFeatures(env));
3192
3193
  auto need_immediate_callback_string =
3194
1750
      FIXED_ONE_BYTE_STRING(env->isolate(), "_needImmediateCallback");
3195
8750
  CHECK(process->SetAccessor(env->context(), need_immediate_callback_string,
3196
                             NeedImmediateCallbackGetter,
3197
                             NeedImmediateCallbackSetter,
3198
                             env->as_external()).FromJust());
3199
3200
  // -e, --eval
3201
1750
  if (eval_string) {
3202
335
    READONLY_PROPERTY(process,
3203
                      "_eval",
3204
                      String::NewFromUtf8(env->isolate(), eval_string));
3205
  }
3206
3207
  // -p, --print
3208
1750
  if (print_eval) {
3209
132
    READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
3210
  }
3211
3212
  // -c, --check
3213
1750
  if (syntax_check_only) {
3214
132
    READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate()));
3215
  }
3216
3217
  // -i, --interactive
3218
1750
  if (force_repl) {
3219
102
    READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
3220
  }
3221
3222
1750
  if (preload_module_count) {
3223
13
    CHECK(preload_modules);
3224
13
    Local<Array> array = Array::New(env->isolate());
3225
30
    for (unsigned int i = 0; i < preload_module_count; ++i) {
3226
      Local<String> module = String::NewFromUtf8(env->isolate(),
3227
17
                                                 preload_modules[i]);
3228
34
      array->Set(i, module);
3229
    }
3230
52
    READONLY_PROPERTY(process,
3231
                      "_preload_modules",
3232
                      array);
3233
3234
13
    delete[] preload_modules;
3235
13
    preload_modules = nullptr;
3236
13
    preload_module_count = 0;
3237
  }
3238
3239
  // --no-deprecation
3240
1750
  if (no_deprecation) {
3241
6
    READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
3242
  }
3243
3244
1750
  if (no_process_warnings) {
3245
42
    READONLY_PROPERTY(process, "noProcessWarnings", True(env->isolate()));
3246
  }
3247
3248
1750
  if (trace_warnings) {
3249
6
    READONLY_PROPERTY(process, "traceProcessWarnings", True(env->isolate()));
3250
  }
3251
3252
  // --throw-deprecation
3253
1750
  if (throw_deprecation) {
3254
    READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate()));
3255
  }
3256
3257
#ifdef NODE_NO_BROWSER_GLOBALS
3258
  // configure --no-browser-globals
3259
  READONLY_PROPERTY(process, "_noBrowserGlobals", True(env->isolate()));
3260
#endif  // NODE_NO_BROWSER_GLOBALS
3261
3262
  // --prof-process
3263
1750
  if (prof_process) {
3264
    READONLY_PROPERTY(process, "profProcess", True(env->isolate()));
3265
  }
3266
3267
  // --trace-deprecation
3268
1750
  if (trace_deprecation) {
3269
6
    READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
3270
  }
3271
3272
  // --debug-brk
3273
1750
  if (debug_options.wait_for_connect()) {
3274
12
    READONLY_PROPERTY(process, "_debugWaitConnect", True(env->isolate()));
3275
  }
3276
3277
  // --security-revert flags
3278
#define V(code, _, __)                                                        \
3279
  do {                                                                        \
3280
    if (IsReverted(REVERT_ ## code)) {                                        \
3281
      READONLY_PROPERTY(process, "REVERT_" #code, True(env->isolate()));      \
3282
    }                                                                         \
3283
  } while (0);
3284
  REVERSIONS(V)
3285
#undef V
3286
3287
1750
  size_t exec_path_len = 2 * PATH_MAX;
3288
1750
  char* exec_path = new char[exec_path_len];
3289
1750
  Local<String> exec_path_value;
3290
1750
  if (uv_exepath(exec_path, &exec_path_len) == 0) {
3291
    exec_path_value = String::NewFromUtf8(env->isolate(),
3292
                                          exec_path,
3293
                                          String::kNormalString,
3294
1750
                                          exec_path_len);
3295
  } else {
3296
    exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
3297
  }
3298
5250
  process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "execPath"),
3299
1750
               exec_path_value);
3300
1750
  delete[] exec_path;
3301
3302
1750
  auto debug_port_string = FIXED_ONE_BYTE_STRING(env->isolate(), "debugPort");
3303
8750
  CHECK(process->SetAccessor(env->context(),
3304
                             debug_port_string,
3305
                             DebugPortGetter,
3306
                             DebugPortSetter,
3307
                             env->as_external()).FromJust());
3308
3309
  // define various internal methods
3310
  env->SetMethod(process,
3311
                 "_startProfilerIdleNotifier",
3312
1750
                 StartProfilerIdleNotifier);
3313
  env->SetMethod(process,
3314
                 "_stopProfilerIdleNotifier",
3315
1750
                 StopProfilerIdleNotifier);
3316
1750
  env->SetMethod(process, "_getActiveRequests", GetActiveRequests);
3317
1750
  env->SetMethod(process, "_getActiveHandles", GetActiveHandles);
3318
1750
  env->SetMethod(process, "reallyExit", Exit);
3319
1750
  env->SetMethod(process, "abort", Abort);
3320
1750
  env->SetMethod(process, "chdir", Chdir);
3321
1750
  env->SetMethod(process, "cwd", Cwd);
3322
3323
1750
  env->SetMethod(process, "umask", Umask);
3324
3325
#if defined(__POSIX__) && !defined(__ANDROID__)
3326
1750
  env->SetMethod(process, "getuid", GetUid);
3327
1750
  env->SetMethod(process, "geteuid", GetEUid);
3328
1750
  env->SetMethod(process, "setuid", SetUid);
3329
1750
  env->SetMethod(process, "seteuid", SetEUid);
3330
3331
1750
  env->SetMethod(process, "setgid", SetGid);
3332
1750
  env->SetMethod(process, "setegid", SetEGid);
3333
1750
  env->SetMethod(process, "getgid", GetGid);
3334
1750
  env->SetMethod(process, "getegid", GetEGid);
3335
3336
1750
  env->SetMethod(process, "getgroups", GetGroups);
3337
1750
  env->SetMethod(process, "setgroups", SetGroups);
3338
1750
  env->SetMethod(process, "initgroups", InitGroups);
3339
#endif  // __POSIX__ && !defined(__ANDROID__)
3340
3341
1750
  env->SetMethod(process, "_kill", Kill);
3342
3343
1750
  env->SetMethod(process, "_debugProcess", DebugProcess);
3344
1750
  env->SetMethod(process, "_debugPause", DebugPause);
3345
1750
  env->SetMethod(process, "_debugEnd", DebugEnd);
3346
3347
1750
  env->SetMethod(process, "hrtime", Hrtime);
3348
3349
1750
  env->SetMethod(process, "cpuUsage", CPUUsage);
3350
3351
1750
  env->SetMethod(process, "dlopen", DLOpen);
3352
3353
1750
  env->SetMethod(process, "uptime", Uptime);
3354
1750
  env->SetMethod(process, "memoryUsage", MemoryUsage);
3355
3356
1750
  env->SetMethod(process, "binding", Binding);
3357
1750
  env->SetMethod(process, "_linkedBinding", LinkedBinding);
3358
3359
1750
  env->SetMethod(process, "_setupProcessObject", SetupProcessObject);
3360
1750
  env->SetMethod(process, "_setupNextTick", SetupNextTick);
3361
1750
  env->SetMethod(process, "_setupPromises", SetupPromises);
3362
1750
  env->SetMethod(process, "_setupDomainUse", SetupDomainUse);
3363
3364
  // pre-set _events object for faster emit checks
3365
1750
  Local<Object> events_obj = Object::New(env->isolate());
3366
10500
  CHECK(events_obj->SetPrototype(env->context(),
3367
                                 Null(env->isolate())).FromJust());
3368
5250
  process->Set(env->events_string(), events_obj);
3369
1750
}
3370
3371
3372
#undef READONLY_PROPERTY
3373
3374
3375
void SignalExit(int signo) {
3376
  uv_tty_reset_mode();
3377
  if (trace_enabled) {
3378
    tracing_agent->Stop();
3379
  }
3380
#ifdef __FreeBSD__
3381
  // FreeBSD has a nasty bug, see RegisterSignalHandler for details
3382
  struct sigaction sa;
3383
  memset(&sa, 0, sizeof(sa));
3384
  sa.sa_handler = SIG_DFL;
3385
  CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
3386
#endif
3387
  raise(signo);
3388
}
3389
3390
3391
// Most of the time, it's best to use `console.error` to write
3392
// to the process.stderr stream.  However, in some cases, such as
3393
// when debugging the stream.Writable class or the process.nextTick
3394
// function, it is useful to bypass JavaScript entirely.
3395
7
static void RawDebug(const FunctionCallbackInfo<Value>& args) {
3396


28
  CHECK(args.Length() == 1 && args[0]->IsString() &&
3397
        "must be called with a single string");
3398
21
  node::Utf8Value message(args.GetIsolate(), args[0]);
3399
7
  PrintErrorString("%s\n", *message);
3400
7
  fflush(stderr);
3401
7
}
3402
3403
3404
1750
void LoadEnvironment(Environment* env) {
3405
3412
  HandleScope handle_scope(env->isolate());
3406
3407
3412
  TryCatch try_catch(env->isolate());
3408
3409
  // Disable verbose mode to stop FatalException() handler from trying
3410
  // to handle the exception. Errors this early in the start-up phase
3411
  // are not safe to ignore.
3412
1750
  try_catch.SetVerbose(false);
3413
3414
  // Execute the lib/internal/bootstrap_node.js file which was included as a
3415
  // static C string in node_natives.h by node_js2c.
3416
  // 'internal_bootstrap_node_native' is the string containing that source code.
3417
1750
  Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(),
3418
                                                    "bootstrap_node.js");
3419
1750
  Local<Value> f_value = ExecuteString(env, MainSource(env), script_name);
3420
1750
  if (try_catch.HasCaught())  {
3421
    ReportException(env, try_catch);
3422
    exit(10);
3423
  }
3424
  // The bootstrap_node.js file returns a function 'f'
3425
1750
  CHECK(f_value->IsFunction());
3426
1750
  Local<Function> f = Local<Function>::Cast(f_value);
3427
3428
  // Add a reference to the global object
3429
1750
  Local<Object> global = env->context()->Global();
3430
3431
#if defined HAVE_DTRACE || defined HAVE_ETW
3432
  InitDTrace(env, global);
3433
#endif
3434
3435
#if defined HAVE_LTTNG
3436
  InitLTTNG(env, global);
3437
#endif
3438
3439
#if defined HAVE_PERFCTR
3440
  InitPerfCounters(env, global);
3441
#endif
3442
3443
  // Enable handling of uncaught exceptions
3444
  // (FatalException(), break on uncaught exception in debugger)
3445
  //
3446
  // This is not strictly necessary since it's almost impossible
3447
  // to attach the debugger fast enought to break on exception
3448
  // thrown during process startup.
3449
1750
  try_catch.SetVerbose(true);
3450
3451
1750
  env->SetMethod(env->process_object(), "_rawDebug", RawDebug);
3452
3453
  // Expose the global object as a property on itself
3454
  // (Allows you to set stuff on `global` from anywhere in JavaScript.)
3455
3500
  global->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global);
3456
3457
  // Now we call 'f' with the 'process' variable that we've built up with
3458
  // all our bindings. Inside bootstrap_node.js and internal/process we'll
3459
  // take care of assigning things to their places.
3460
3461
  // We start the process this way in order to be more modular. Developers
3462
  // who do not like how bootstrap_node.js sets up the module system but do
3463
  // like Node's I/O bindings may want to replace 'f' with their own function.
3464
3500
  Local<Value> arg = env->process_object();
3465
5250
  f->Call(Null(env->isolate()), 1, &arg);
3466
1662
}
3467
3468
static void PrintHelp() {
3469
  // XXX: If you add an option here, please also add it to doc/node.1 and
3470
  // doc/api/cli.md
3471
  printf("Usage: node [options] [ -e script | script.js ] [arguments] \n"
3472
         "       node debug script.js [arguments] \n"
3473
         "\n"
3474
         "Options:\n"
3475
         "  -v, --version            print Node.js version\n"
3476
         "  -e, --eval script        evaluate script\n"
3477
         "  -p, --print              evaluate script and print result\n"
3478
         "  -c, --check              syntax check script without executing\n"
3479
         "  -i, --interactive        always enter the REPL even if stdin\n"
3480
         "                           does not appear to be a terminal\n"
3481
         "  -r, --require            module to preload (option can be "
3482
         "repeated)\n"
3483
         "  --no-deprecation         silence deprecation warnings\n"
3484
         "  --trace-deprecation      show stack traces on deprecations\n"
3485
         "  --throw-deprecation      throw an exception on deprecations\n"
3486
         "  --no-warnings            silence all process warnings\n"
3487
         "  --trace-warnings         show stack traces on process warnings\n"
3488
         "  --trace-sync-io          show stack trace when use of sync IO\n"
3489
         "                           is detected after the first tick\n"
3490
         "  --trace-events-enabled   track trace events\n"
3491
         "  --trace-event-categories comma separated list of trace event\n"
3492
         "                           categories to record\n"
3493
         "  --track-heap-objects     track heap object allocations for heap "
3494
         "snapshots\n"
3495
         "  --prof-process           process v8 profiler output generated\n"
3496
         "                           using --prof\n"
3497
         "  --zero-fill-buffers      automatically zero-fill all newly "
3498
         "allocated\n"
3499
         "                           Buffer and SlowBuffer instances\n"
3500
         "  --v8-options             print v8 command line options\n"
3501
         "  --v8-pool-size=num       set v8's thread pool size\n"
3502
#if HAVE_OPENSSL
3503
         "  --tls-cipher-list=val    use an alternative default TLS cipher "
3504
         "list\n"
3505
#if NODE_FIPS_MODE
3506
         "  --enable-fips            enable FIPS crypto at startup\n"
3507
         "  --force-fips             force FIPS crypto (cannot be disabled)\n"
3508
#endif  /* NODE_FIPS_MODE */
3509
         "  --openssl-config=path    load OpenSSL configuration file from the\n"
3510
         "                           specified path\n"
3511
#endif /* HAVE_OPENSSL */
3512
#if defined(NODE_HAVE_I18N_SUPPORT)
3513
         "  --icu-data-dir=dir       set ICU data load path to dir\n"
3514
         "                           (overrides NODE_ICU_DATA)\n"
3515
#if !defined(NODE_HAVE_SMALL_ICU)
3516
         "                           note: linked-in ICU data is present\n"
3517
#endif
3518
         "  --preserve-symlinks      preserve symbolic links when resolving\n"
3519
         "                           and caching modules\n"
3520
#endif
3521
         "\n"
3522
         "Environment variables:\n"
3523
         "NODE_DEBUG                 ','-separated list of core modules that\n"
3524
         "                           should print debug information\n"
3525
         "NODE_DISABLE_COLORS        set to 1 to disable colors in the REPL\n"
3526
         "NODE_EXTRA_CA_CERTS        path to additional CA certificates file\n"
3527
#if defined(NODE_HAVE_I18N_SUPPORT)
3528
         "NODE_ICU_DATA              data path for ICU (Intl object) data\n"
3529
#if !defined(NODE_HAVE_SMALL_ICU)
3530
         "                           (will extend linked-in data)\n"
3531
#endif
3532
#endif
3533
#ifdef _WIN32
3534
         "NODE_PATH                  ';'-separated list of directories\n"
3535
#else
3536
         "NODE_PATH                  ':'-separated list of directories\n"
3537
#endif
3538
         "                           prefixed to the module search path\n"
3539
         "NODE_REPL_HISTORY          path to the persistent REPL history file\n"
3540
         "\n"
3541
         "Documentation can be found at https://nodejs.org/\n");
3542
}
3543
3544
3545
// Parse command line arguments.
3546
//
3547
// argv is modified in place. exec_argv and v8_argv are out arguments that
3548
// ParseArgs() allocates memory for and stores a pointer to the output
3549
// vector in.  The caller should free them with delete[].
3550
//
3551
// On exit:
3552
//
3553
//  * argv contains the arguments with node and V8 options filtered out.
3554
//  * exec_argv contains both node and V8 options and nothing else.
3555
//  * v8_argv contains argv[0] plus any V8 options
3556
1757
static void ParseArgs(int* argc,
3557
                      const char** argv,
3558
                      int* exec_argc,
3559
                      const char*** exec_argv,
3560
                      int* v8_argc,
3561
                      const char*** v8_argv) {
3562
1757
  const unsigned int nargs = static_cast<unsigned int>(*argc);
3563
1757
  const char** new_exec_argv = new const char*[nargs];
3564
1757
  const char** new_v8_argv = new const char*[nargs];
3565
1757
  const char** new_argv = new const char*[nargs];
3566
1757
  const char** local_preload_modules = new const char*[nargs];
3567
3568
5854
  for (unsigned int i = 0; i < nargs; ++i) {
3569
4097
    new_exec_argv[i] = nullptr;
3570
4097
    new_v8_argv[i] = nullptr;
3571
4097
    new_argv[i] = nullptr;
3572
4097
    local_preload_modules[i] = nullptr;
3573
  }
3574
3575
  // exec_argv starts with the first option, the other two start with argv[0].
3576
1757
  unsigned int new_exec_argc = 0;
3577
1757
  unsigned int new_v8_argc = 1;
3578
1757
  unsigned int new_argc = 1;
3579
1757
  new_v8_argv[0] = argv[0];
3580
1757
  new_argv[0] = argv[0];
3581
3582
1757
  unsigned int index = 1;
3583
1757
  bool short_circuit = false;
3584

2255
  while (index < nargs && argv[index][0] == '-' && !short_circuit) {
3585
252
    const char* const arg = argv[index];
3586
252
    unsigned int args_consumed = 1;
3587
3588
1008
    if (debug_options.ParseOption(arg)) {
3589
      // Done, consumed by DebugOptions::ParseOption().
3590

229
    } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
3591
2
      printf("%s\n", NODE_VERSION);
3592
2
      exit(0);
3593

227
    } else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
3594
      PrintHelp();
3595
      exit(0);
3596

450
    } else if (strcmp(arg, "--eval") == 0 ||
3597
392
               strcmp(arg, "-e") == 0 ||
3598
335
               strcmp(arg, "--print") == 0 ||
3599
325
               strcmp(arg, "-pe") == 0 ||
3600
159
               strcmp(arg, "-p") == 0) {
3601
80
      bool is_eval = strchr(arg, 'e') != nullptr;
3602
80
      bool is_print = strchr(arg, 'p') != nullptr;
3603

80
      print_eval = print_eval || is_print;
3604
      // --eval, -e and -pe always require an argument.
3605
80
      if (is_eval == true) {
3606
65
        args_consumed += 1;
3607
65
        eval_string = argv[index + 1];
3608
65
        if (eval_string == nullptr) {
3609
2
          fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3610
1
          exit(9);
3611
        }
3612

30
      } else if ((index + 1 < nargs) &&
3613
30
                 argv[index + 1] != nullptr &&
3614
15
                 argv[index + 1][0] != '-') {
3615
13
        args_consumed += 1;
3616
13
        eval_string = argv[index + 1];
3617
13
        if (strncmp(eval_string, "\\-", 2) == 0) {
3618
          // Starts with "\\-": escaped expression, drop the backslash.
3619
1
          eval_string += 1;
3620
        }
3621
      }
3622

288
    } else if (strcmp(arg, "--require") == 0 ||
3623
141
               strcmp(arg, "-r") == 0) {
3624
17
      const char* module = argv[index + 1];
3625
17
      if (module == nullptr) {
3626
        fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3627
        exit(9);
3628
      }
3629
17
      args_consumed += 1;
3630
17
      local_preload_modules[preload_module_count++] = module;
3631

130
    } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) {
3632
22
      syntax_check_only = true;
3633

108
    } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
3634
15
      force_repl = true;
3635
93
    } else if (strcmp(arg, "--no-deprecation") == 0) {
3636
1
      no_deprecation = true;
3637
92
    } else if (strcmp(arg, "--no-warnings") == 0) {
3638
7
      no_process_warnings = true;
3639
85
    } else if (strcmp(arg, "--trace-warnings") == 0) {
3640
1
      trace_warnings = true;
3641
84
    } else if (strcmp(arg, "--trace-deprecation") == 0) {
3642
1
      trace_deprecation = true;
3643
83
    } else if (strcmp(arg, "--trace-sync-io") == 0) {
3644
1
      trace_sync_io = true;
3645
82
    } else if (strcmp(arg, "--trace-events-enabled") == 0) {
3646
2
      trace_enabled = true;
3647
80
    } else if (strcmp(arg, "--trace-event-categories") == 0) {
3648
1
      const char* categories = argv[index + 1];
3649
1
      if (categories == nullptr) {
3650
        fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
3651
        exit(9);
3652
      }
3653
1
      args_consumed += 1;
3654
1
      trace_enabled_categories = categories;
3655
79
    } else if (strcmp(arg, "--track-heap-objects") == 0) {
3656
      track_heap_objects = true;
3657
79
    } else if (strcmp(arg, "--throw-deprecation") == 0) {
3658
      throw_deprecation = true;
3659
79
    } else if (strncmp(arg, "--security-revert=", 18) == 0) {
3660
      const char* cve = arg + 18;
3661
      Revert(cve);
3662
79
    } else if (strcmp(arg, "--preserve-symlinks") == 0) {
3663
3
      config_preserve_symlinks = true;
3664
76
    } else if (strcmp(arg, "--prof-process") == 0) {
3665
      prof_process = true;
3666
      short_circuit = true;
3667
76
    } else if (strcmp(arg, "--zero-fill-buffers") == 0) {
3668
1
      zero_fill_all_buffers = true;
3669
75