-
Notifications
You must be signed in to change notification settings - Fork 576
/
child_process.ts
119 lines (105 loc) · 3.3 KB
/
child_process.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
// This module implements 'child_process' module of Node.JS API.
// ref: https://nodejs.org/api/child_process.html
import {
ChildProcess,
ChildProcessOptions,
stdioStringToArray,
} from "./internal/child_process.ts";
import { validateString } from "./internal/validators.js";
import {
ERR_CHILD_PROCESS_IPC_REQUIRED,
ERR_INVALID_ARG_VALUE,
} from "./_errors.ts";
import { process } from "./process.ts";
const denoCompatArgv = [
"run",
"--compat",
"--unstable",
"--no-check",
"--allow-all",
];
/**
* Spawns a new Node.js process + fork.
* @param modulePath
* @param args
* @param option
* @returns {ChildProcess}
*/
export function fork(
modulePath: string, /* args?: string[], options?: ForkOptions*/
) {
validateString(modulePath, "modulePath");
// Get options and args arguments.
let execArgv;
let options: SpawnOptions & {
execArgv?: string;
execPath?: string;
silent?: boolean;
} = {};
let args: string[] = [];
let pos = 1;
if (pos < arguments.length && Array.isArray(arguments[pos])) {
args = arguments[pos++];
}
if (pos < arguments.length && arguments[pos] == null) {
pos++;
}
if (pos < arguments.length && arguments[pos] != null) {
if (typeof arguments[pos] !== "object") {
throw new ERR_INVALID_ARG_VALUE(`arguments[${pos}]`, arguments[pos]);
}
options = { ...arguments[pos++] };
}
// Prepare arguments for fork:
execArgv = options.execArgv || process.execArgv;
if (execArgv === process.execArgv && process._eval != null) {
const index = execArgv.lastIndexOf(process._eval);
if (index > 0) {
// Remove the -e switch to avoid fork bombing ourselves.
execArgv = execArgv.slice(0);
execArgv.splice(index - 1, 2);
}
}
args = [...denoCompatArgv, ...execArgv, modulePath, ...args];
if (typeof options.stdio === "string") {
options.stdio = stdioStringToArray(options.stdio, "ipc");
} else if (!Array.isArray(options.stdio)) {
// Use a separate fd=3 for the IPC channel. Inherit stdin, stdout,
// and stderr from the parent if silent isn't set.
options.stdio = stdioStringToArray(
options.silent ? "pipe" : "inherit",
"ipc",
);
} else if (!options.stdio.includes("ipc")) {
throw new ERR_CHILD_PROCESS_IPC_REQUIRED("options.stdio");
}
options.execPath = options.execPath || Deno.execPath();
options.shell = false;
return spawn(options.execPath, args, options);
}
// deno-lint-ignore no-empty-interface
interface SpawnOptions extends ChildProcessOptions {}
export function spawn(command: string): ChildProcess;
export function spawn(command: string, options: SpawnOptions): ChildProcess;
export function spawn(command: string, args: string[]): ChildProcess;
export function spawn(
command: string,
args: string[],
options: SpawnOptions,
): ChildProcess;
/**
* Spawns a child process using `command`.
*/
export function spawn(
command: string,
argsOrOptions?: string[] | SpawnOptions,
maybeOptions?: SpawnOptions,
): ChildProcess {
const args = Array.isArray(argsOrOptions) ? argsOrOptions : [];
const options = !Array.isArray(argsOrOptions) && argsOrOptions != null
? argsOrOptions
: maybeOptions;
return new ChildProcess(command, args, options);
}
export default { fork, spawn };