When the underlying execve(2) system call fails, process.execve() previously printed an error to stderr and called ABORT(), preventing JS code from detecting or recovering from common failures such as a missing binary. Throw an ErrnoException instead, carrying the standard code, errno, syscall, and path properties. To leave the process in a clean state when execve(2) fails, no longer run native AtExit callbacks before the call (their in-memory effects are discarded on success anyway), and snapshot and restore the FD_CLOEXEC flags on stdio so a failed call has no observable side effects. Rename and update test-process-execve-abort.js accordingly and document the new behavior. Signed-off-by: Bryan English <bryan@bryanenglish.com> PR-URL: https://github.com/nodejs/node/pull/62878 Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
39 lines
1.1 KiB
JavaScript
39 lines
1.1 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const { isMainThread } = require('worker_threads');
|
|
|
|
if (!isMainThread) {
|
|
common.skip('process.execve is not available in Workers');
|
|
} else if (common.isWindows || common.isIBMi) {
|
|
common.skip('process.execve is not available in Windows or IBM i');
|
|
}
|
|
|
|
assert.throws(
|
|
() => {
|
|
process.execve(
|
|
`${process.execPath}_non_existing`,
|
|
[process.execPath, 'arg'],
|
|
);
|
|
},
|
|
(err) => {
|
|
assert.ok(err instanceof Error);
|
|
assert.strictEqual(err.code, 'ENOENT');
|
|
assert.strictEqual(err.syscall, 'execve');
|
|
assert.strictEqual(typeof err.errno, 'number');
|
|
assert.ok(err.errno > 0, `expected positive errno, got ${err.errno}`);
|
|
assert.match(err.path, /_non_existing$/);
|
|
return true;
|
|
},
|
|
);
|
|
|
|
assert.strictEqual(process.stdout.writable, true);
|
|
assert.strictEqual(process.stderr.writable, true);
|
|
assert.strictEqual(typeof process.pid, 'number');
|
|
|
|
let tickFired = false;
|
|
process.nextTick(common.mustCall(() => { tickFired = true; }));
|
|
setImmediate(common.mustCall(() => {
|
|
assert.strictEqual(tickFired, true);
|
|
}));
|