Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 57f29b7

Browse filesBrowse files
joyeecheungtargos
authored andcommitted
bootstrap: use different scripts to setup different configurations
This patch splits the handling of `isMainThread` and `ownsProcessState` from conditionals in `lib/internal/bootstrap/node.js` into different scripts under `lib/internal/bootstrap/switches/`, and call them accordingly from C++ after `node.js` is run. This: - Creates a common denominator of the main thread and the worker thread bootstrap that can be snapshotted and shared by both. - Makes it possible to override the configurations on-the-fly. PR-URL: #30862 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 1c17f42 commit 57f29b7
Copy full SHA for 57f29b7

File tree

Expand file treeCollapse file tree

14 files changed

+568
-545
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

14 files changed

+568
-545
lines changed
Open diff view settings
Collapse file

‎lib/internal/bootstrap/node.js‎

Copy file name to clipboardExpand all lines: lib/internal/bootstrap/node.js
+18-99Lines changed: 18 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
// This file is invoked by `node::RunBootstrapping()` in `src/node.cc`, and is
44
// responsible for setting up node.js core before executing main scripts
55
// under `lib/internal/main/`.
6-
// This file is currently run to bootstrap both the main thread and the worker
7-
// threads. Some setups are conditional, controlled with isMainThread and
8-
// ownsProcessState.
6+
//
97
// This file is expected not to perform any asynchronous operations itself
108
// when being executed - those should be done in either
119
// `lib/internal/bootstrap/pre_execution.js` or in main scripts. The majority
@@ -22,16 +20,21 @@
2220
// module loaders, including `process.binding()`, `process._linkedBinding()`,
2321
// `internalBinding()` and `NativeModule`.
2422
//
25-
// After this file is run, one of the main scripts under `lib/internal/main/`
26-
// will be selected by C++ to start the actual execution. The main scripts may
27-
// run additional setups exported by `lib/internal/bootstrap/pre_execution.js`,
28-
// depending on the execution mode.
23+
// This file is run to bootstrap both the main thread and the worker threads.
24+
// After this file is run, certain properties are setup according to the
25+
// configuration of the Node.js instance using the files in
26+
// `lib/internal/bootstrap/switches/`.
27+
//
28+
// Then, depending on how the Node.js instance is launched, one of the main
29+
// scripts in `lib/internal/main` will be selected by C++ to start the actual
30+
// execution. They may run additional setups exported by
31+
// `lib/internal/bootstrap/pre_execution.js` depending on the runtime states.
2932

3033
'use strict';
3134

3235
// This file is compiled as if it's wrapped in a function with arguments
3336
// passed by node::RunBootstrapping()
34-
/* global process, require, internalBinding, isMainThread, ownsProcessState */
37+
/* global process, require, internalBinding */
3538

3639
setupPrepareStackTrace();
3740

@@ -54,48 +57,12 @@ setupBuffer();
5457
process.domain = null;
5558
process._exiting = false;
5659

57-
// Bootstrappers for all threads, including worker threads and main thread
58-
const perThreadSetup = require('internal/process/per_thread');
59-
// Bootstrappers for the main thread only
60-
let mainThreadSetup;
61-
// Bootstrappers for the worker threads only
62-
let workerThreadSetup;
63-
if (ownsProcessState) {
64-
mainThreadSetup = require(
65-
'internal/process/main_thread_only'
66-
);
67-
} else {
68-
workerThreadSetup = require(
69-
'internal/process/worker_thread_only'
70-
);
71-
}
72-
7360
// process.config is serialized config.gypi
7461
process.config = JSONParse(internalBinding('native_module').config);
7562

63+
// Bootstrappers for all threads, including worker threads and main thread
64+
const perThreadSetup = require('internal/process/per_thread');
7665
const rawMethods = internalBinding('process_methods');
77-
// Set up methods and events on the process object for the main thread
78-
if (isMainThread) {
79-
process.abort = rawMethods.abort;
80-
const wrapped = mainThreadSetup.wrapProcessMethods(rawMethods);
81-
process.umask = wrapped.umask;
82-
process.chdir = wrapped.chdir;
83-
process.cwd = wrapped.cwd;
84-
85-
// TODO(joyeecheung): deprecate and remove these underscore methods
86-
process._debugProcess = rawMethods._debugProcess;
87-
process._debugEnd = rawMethods._debugEnd;
88-
process._startProfilerIdleNotifier =
89-
rawMethods._startProfilerIdleNotifier;
90-
process._stopProfilerIdleNotifier = rawMethods._stopProfilerIdleNotifier;
91-
} else {
92-
const wrapped = workerThreadSetup.wrapProcessMethods(rawMethods);
93-
94-
process.abort = workerThreadSetup.unavailable('process.abort()');
95-
process.chdir = workerThreadSetup.unavailable('process.chdir()');
96-
process.umask = wrapped.umask;
97-
process.cwd = rawMethods.cwd;
98-
}
9966

10067
// Set up methods on the process object for all threads
10168
{
@@ -119,6 +86,11 @@ if (isMainThread) {
11986
process.memoryUsage = wrapped.memoryUsage;
12087
process.kill = wrapped.kill;
12188
process.exit = wrapped.exit;
89+
90+
process.openStdin = function() {
91+
process.stdin.resume();
92+
return process.stdin;
93+
};
12294
}
12395

12496
const credentials = internalBinding('credentials');
@@ -128,34 +100,6 @@ if (credentials.implementsPosixCredentials) {
128100
process.getgid = credentials.getgid;
129101
process.getegid = credentials.getegid;
130102
process.getgroups = credentials.getgroups;
131-
132-
if (ownsProcessState) {
133-
const wrapped = mainThreadSetup.wrapPosixCredentialSetters(credentials);
134-
process.initgroups = wrapped.initgroups;
135-
process.setgroups = wrapped.setgroups;
136-
process.setegid = wrapped.setegid;
137-
process.seteuid = wrapped.seteuid;
138-
process.setgid = wrapped.setgid;
139-
process.setuid = wrapped.setuid;
140-
} else {
141-
process.initgroups =
142-
workerThreadSetup.unavailable('process.initgroups()');
143-
process.setgroups = workerThreadSetup.unavailable('process.setgroups()');
144-
process.setegid = workerThreadSetup.unavailable('process.setegid()');
145-
process.seteuid = workerThreadSetup.unavailable('process.seteuid()');
146-
process.setgid = workerThreadSetup.unavailable('process.setgid()');
147-
process.setuid = workerThreadSetup.unavailable('process.setuid()');
148-
}
149-
}
150-
151-
if (isMainThread) {
152-
const { getStdout, getStdin, getStderr } =
153-
require('internal/process/stdio').getMainThreadStdio();
154-
setupProcessStdio(getStdout, getStdin, getStderr);
155-
} else {
156-
const { getStdout, getStdin, getStderr } =
157-
workerThreadSetup.createStdioGetters();
158-
setupProcessStdio(getStdout, getStdin, getStderr);
159103
}
160104

161105
// Setup the callbacks that node::AsyncWrap will call when there are hooks to
@@ -343,31 +287,6 @@ function setupProcessObject() {
343287
});
344288
}
345289

346-
function setupProcessStdio(getStdout, getStdin, getStderr) {
347-
ObjectDefineProperty(process, 'stdout', {
348-
configurable: true,
349-
enumerable: true,
350-
get: getStdout
351-
});
352-
353-
ObjectDefineProperty(process, 'stderr', {
354-
configurable: true,
355-
enumerable: true,
356-
get: getStderr
357-
});
358-
359-
ObjectDefineProperty(process, 'stdin', {
360-
configurable: true,
361-
enumerable: true,
362-
get: getStdin
363-
});
364-
365-
process.openStdin = function() {
366-
process.stdin.resume();
367-
return process.stdin;
368-
};
369-
}
370-
371290
function setupGlobalProxy() {
372291
ObjectDefineProperty(global, SymbolToStringTag, {
373292
value: 'global',
Collapse file

‎lib/internal/bootstrap/pre_execution.js‎

Copy file name to clipboardExpand all lines: lib/internal/bootstrap/pre_execution.js
+1-17Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ function prepareMainThreadExecution(expandArgv1 = false) {
3737

3838
setupDebugEnv();
3939

40-
// Only main thread receives signals.
41-
setupSignalHandlers();
42-
4340
// Process initial diagnostic reporting configuration, if present.
4441
initializeReport();
4542
initializeReportSignalHandlers(); // Main-thread-only.
@@ -175,20 +172,7 @@ function setupDebugEnv() {
175172
}
176173
}
177174

178-
function setupSignalHandlers() {
179-
const {
180-
createSignalHandlers
181-
} = require('internal/process/main_thread_only');
182-
const {
183-
startListeningIfSignal,
184-
stopListeningIfSignal
185-
} = createSignalHandlers();
186-
process.on('newListener', startListeningIfSignal);
187-
process.on('removeListener', stopListeningIfSignal);
188-
}
189-
190-
// This has to be called after both initializeReport() and
191-
// setupSignalHandlers() are called
175+
// This has to be called after initializeReport() is called
192176
function initializeReportSignalHandlers() {
193177
if (!getOptionValue('--experimental-report')) {
194178
return;
Collapse file
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
3+
const credentials = internalBinding('credentials');
4+
5+
if (credentials.implementsPosixCredentials) {
6+
// TODO: this should be detached from ERR_WORKER_UNSUPPORTED_OPERATION
7+
const { unavailable } = require('internal/process/worker_thread_only');
8+
9+
process.initgroups = unavailable('process.initgroups()');
10+
process.setgroups = unavailable('process.setgroups()');
11+
process.setegid = unavailable('process.setegid()');
12+
process.seteuid = unavailable('process.seteuid()');
13+
process.setgid = unavailable('process.setgid()');
14+
process.setuid = unavailable('process.setuid()');
15+
}
16+
17+
// ---- keep the attachment of the wrappers above so that it's easier to ----
18+
// ---- compare the setups side-by-side -----
Collapse file
+96Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
'use strict';
2+
3+
const credentials = internalBinding('credentials');
4+
5+
if (credentials.implementsPosixCredentials) {
6+
const wrapped = wrapPosixCredentialSetters(credentials);
7+
8+
process.initgroups = wrapped.initgroups;
9+
process.setgroups = wrapped.setgroups;
10+
process.setegid = wrapped.setegid;
11+
process.seteuid = wrapped.seteuid;
12+
process.setgid = wrapped.setgid;
13+
process.setuid = wrapped.setuid;
14+
}
15+
16+
// ---- keep the attachment of the wrappers above so that it's easier to ----
17+
// ---- compare the setups side-by-side -----
18+
19+
function wrapPosixCredentialSetters(credentials) {
20+
const {
21+
ArrayIsArray,
22+
} = primordials;
23+
const {
24+
codes: {
25+
ERR_INVALID_ARG_TYPE,
26+
ERR_UNKNOWN_CREDENTIAL
27+
}
28+
} = require('internal/errors');
29+
const {
30+
validateUint32
31+
} = require('internal/validators');
32+
33+
const {
34+
initgroups: _initgroups,
35+
setgroups: _setgroups,
36+
setegid: _setegid,
37+
seteuid: _seteuid,
38+
setgid: _setgid,
39+
setuid: _setuid
40+
} = credentials;
41+
42+
function initgroups(user, extraGroup) {
43+
validateId(user, 'user');
44+
validateId(extraGroup, 'extraGroup');
45+
// Result is 0 on success, 1 if user is unknown, 2 if group is unknown.
46+
const result = _initgroups(user, extraGroup);
47+
if (result === 1) {
48+
throw new ERR_UNKNOWN_CREDENTIAL('User', user);
49+
} else if (result === 2) {
50+
throw new ERR_UNKNOWN_CREDENTIAL('Group', extraGroup);
51+
}
52+
}
53+
54+
function setgroups(groups) {
55+
if (!ArrayIsArray(groups)) {
56+
throw new ERR_INVALID_ARG_TYPE('groups', 'Array', groups);
57+
}
58+
for (let i = 0; i < groups.length; i++) {
59+
validateId(groups[i], `groups[${i}]`);
60+
}
61+
// Result is 0 on success. A positive integer indicates that the
62+
// corresponding group was not found.
63+
const result = _setgroups(groups);
64+
if (result > 0) {
65+
throw new ERR_UNKNOWN_CREDENTIAL('Group', groups[result - 1]);
66+
}
67+
}
68+
69+
function wrapIdSetter(type, method) {
70+
return function(id) {
71+
validateId(id, 'id');
72+
// Result is 0 on success, 1 if credential is unknown.
73+
const result = method(id);
74+
if (result === 1) {
75+
throw new ERR_UNKNOWN_CREDENTIAL(type, id);
76+
}
77+
};
78+
}
79+
80+
function validateId(id, name) {
81+
if (typeof id === 'number') {
82+
validateUint32(id, name);
83+
} else if (typeof id !== 'string') {
84+
throw new ERR_INVALID_ARG_TYPE(name, ['number', 'string'], id);
85+
}
86+
}
87+
88+
return {
89+
initgroups,
90+
setgroups,
91+
setegid: wrapIdSetter('Group', _setegid),
92+
seteuid: wrapIdSetter('User', _seteuid),
93+
setgid: wrapIdSetter('Group', _setgid),
94+
setuid: wrapIdSetter('User', _setuid)
95+
};
96+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.