| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 373ec2d commit 2ab9848
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -41,7 +41,7 @@ const dgram = require('dgram'); | |||
| 41 | 41 | const inspect = require('internal/util/inspect').inspect; | |
| 42 | 42 | const assert = require('internal/assert'); | |
| 43 | 43 | ||
| 44 | - const { Process } = internalBinding('process_wrap'); | ||
| 44 | + const { Process, constants: processConstants } = internalBinding('process_wrap'); | ||
| 45 | 45 | const { | |
| 46 | 46 | WriteWrap, | |
| 47 | 47 | kReadBytesOrError, | |
@@ -397,7 +397,24 @@ ChildProcess.prototype.spawn = function spawn(options) { | |||
| 397 | 397 | childProcessSpawn.start.publish({ process: this, options }); | |
| 398 | 398 | } | |
| 399 | 399 | ||
| 400 | - const err = this._handle.spawn(options); | ||
| 400 | + let spawnFlags = 0; | ||
| 401 | + if (options.detached) | ||
| 402 | + spawnFlags |= processConstants.kProcessFlagDetached; | ||
| 403 | + if (options.windowsHide) | ||
| 404 | + spawnFlags |= processConstants.kProcessFlagWindowsHide; | ||
| 405 | + if (options.windowsVerbatimArguments) | ||
| 406 | + spawnFlags |= processConstants.kProcessFlagWindowsVerbatimArguments; | ||
| 407 | + | ||
| 408 | + const err = this._handle.spawn( | ||
| 409 | + options.file, | ||
| 410 | + options.args, | ||
| 411 | + options.cwd, | ||
| 412 | + options.envPairs, | ||
| 413 | + options.stdio, | ||
| 414 | + spawnFlags, | ||
| 415 | + options.uid, | ||
| 416 | + options.gid, | ||
| 417 | + ); | ||
| 401 | 418 | ||
| 402 | 419 | // Run-time errors should emit an error, not throw an exception. | |
| 403 | 420 | if (err === UV_EACCES || | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -49,10 +49,18 @@ using v8::Nothing; | |||
| 49 | 49 | using v8::Number; | |
| 50 | 50 | using v8::Object; | |
| 51 | 51 | using v8::String; | |
| 52 | + using v8::Uint32; | ||
| 52 | 53 | using v8::Value; | |
| 53 | 54 | ||
| 54 | 55 | namespace { | |
| 55 | 56 | ||
| 57 | + enum ProcessFlags : uint32_t { | ||
| 58 | + kProcessFlagNone = 0, | ||
| 59 | + kProcessFlagDetached = 1 << 0, | ||
| 60 | + kProcessFlagWindowsHide = 1 << 1, | ||
| 61 | + kProcessFlagWindowsVerbatimArguments = 1 << 2, | ||
| 62 | + }; | ||
| 63 | + | ||
| 56 | 64 | class ProcessWrap : public HandleWrap { | |
| 57 | 65 | public: | |
| 58 | 66 | static void Initialize(Local<Object> target, | |
@@ -71,6 +79,12 @@ class ProcessWrap : public HandleWrap { | |||
| 71 | 79 | SetProtoMethod(isolate, constructor, "kill", Kill); | |
| 72 | 80 | ||
| 73 | 81 | SetConstructorFunction(context, target, "Process", constructor); | |
| 82 | + | ||
| 83 | + Local<Object> constants = Object::New(isolate); | ||
| 84 | + NODE_DEFINE_CONSTANT(constants, kProcessFlagDetached); | ||
| 85 | + NODE_DEFINE_CONSTANT(constants, kProcessFlagWindowsHide); | ||
| 86 | + NODE_DEFINE_CONSTANT(constants, kProcessFlagWindowsVerbatimArguments); | ||
| 87 | + target->Set(context, env->constants_string(), constants).Check(); | ||
| 74 | 88 | } | |
| 75 | 89 | ||
| 76 | 90 | static void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |
@@ -118,14 +132,9 @@ class ProcessWrap : public HandleWrap { | |||
| 118 | 132 | ||
| 119 | 133 | static Maybe<void> ParseStdioOptions( | |
| 120 | 134 | Environment* env, | |
| 121 | - Local<Object> js_options, | ||
| 135 | + Local<Value> stdios_val, | ||
| 122 | 136 | std::vector<uv_stdio_container_t>* options_stdio) { | |
| 123 | 137 | Local<Context> context = env->context(); | |
| 124 | - Local<String> stdio_key = env->stdio_string(); | ||
| 125 | - Local<Value> stdios_val; | ||
| 126 | - if (!js_options->Get(context, stdio_key).ToLocal(&stdios_val)) { | ||
| 127 | - return Nothing<void>(); | ||
| 128 | - } | ||
| 129 | 138 | if (!stdios_val->IsArray()) { | |
| 130 | 139 | THROW_ERR_INVALID_ARG_TYPE(env, "options.stdio must be an array"); | |
| 131 | 140 | return Nothing<void>(); | |
@@ -188,46 +197,30 @@ class ProcessWrap : public HandleWrap { | |||
| 188 | 197 | ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); | |
| 189 | 198 | int err = 0; | |
| 190 | 199 | ||
| 191 | - if (!args[0]->IsObject()) { | ||
| 192 | - return THROW_ERR_INVALID_ARG_TYPE(env, "options must be an object"); | ||
| 193 | - } | ||
| 194 | - | ||
| 195 | - Local<Object> js_options = args[0].As<Object>(); | ||
| 196 | - | ||
| 197 | 200 | uv_process_options_t options; | |
| 198 | 201 | memset(&options, 0, sizeof(uv_process_options_t)); | |
| 199 | 202 | ||
| 200 | 203 | options.exit_cb = OnExit; | |
| 201 | 204 | ||
| 202 | - // options.file | ||
| 203 | - Local<Value> file_v; | ||
| 204 | - if (!js_options->Get(context, env->file_string()).ToLocal(&file_v)) { | ||
| 205 | - return; | ||
| 206 | - } | ||
| 207 | - CHECK(file_v->IsString()); | ||
| 208 | - node::Utf8Value file(env->isolate(), file_v); | ||
| 205 | + // args[0] file | ||
| 206 | + CHECK(args[0]->IsString()); | ||
| 207 | + node::Utf8Value file(env->isolate(), args[0]); | ||
| 209 | 208 | options.file = *file; | |
| 210 | 209 | ||
| 211 | 210 | THROW_IF_INSUFFICIENT_PERMISSIONS( | |
| 212 | 211 | env, permission::PermissionScope::kChildProcess, file.ToStringView()); | |
| 213 | 212 | ||
| 214 | - // options.uid | ||
| 215 | - Local<Value> uid_v; | ||
| 216 | - if (!js_options->Get(context, env->uid_string()).ToLocal(&uid_v)) { | ||
| 217 | - return; | ||
| 218 | - } | ||
| 213 | + // args[6] uid | ||
| 214 | + Local<Value> uid_v = args[6]; | ||
| 219 | 215 | if (!uid_v->IsUndefined() && !uid_v->IsNull()) { | |
| 220 | 216 | CHECK(uid_v->IsInt32()); | |
| 221 | 217 | const int32_t uid = uid_v.As<Int32>()->Value(); | |
| 222 | 218 | options.flags |= UV_PROCESS_SETUID; | |
| 223 | 219 | options.uid = static_cast<uv_uid_t>(uid); | |
| 224 | 220 | } | |
| 225 | 221 | ||
| 226 | - // options.gid | ||
| 227 | - Local<Value> gid_v; | ||
| 228 | - if (!js_options->Get(context, env->gid_string()).ToLocal(&gid_v)) { | ||
| 229 | - return; | ||
| 230 | - } | ||
| 222 | + // args[7] gid | ||
| 223 | + Local<Value> gid_v = args[7]; | ||
| 231 | 224 | if (!gid_v->IsUndefined() && !gid_v->IsNull()) { | |
| 232 | 225 | CHECK(gid_v->IsInt32()); | |
| 233 | 226 | const int32_t gid = gid_v.As<Int32>()->Value(); | |
@@ -244,15 +237,11 @@ class ProcessWrap : public HandleWrap { | |||
| 244 | 237 | err = UV_EINVAL; | |
| 245 | 238 | #endif | |
| 246 | 239 | ||
| 247 | - // options.args | ||
| 248 | - Local<Value> argv_v; | ||
| 249 | - if (!js_options->Get(context, env->args_string()).ToLocal(&argv_v)) { | ||
| 250 | - return; | ||
| 251 | - } | ||
| 240 | + // args[1] args | ||
| 252 | 241 | std::vector<char*> options_args; | |
| 253 | 242 | std::vector<std::string> args_vals; | |
| 254 | - if (argv_v->IsArray()) { | ||
| 255 | - Local<Array> js_argv = argv_v.As<Array>(); | ||
| 243 | + if (args[1]->IsArray()) { | ||
| 244 | + Local<Array> js_argv = args[1].As<Array>(); | ||
| 256 | 245 | int argc = js_argv->Length(); | |
| 257 | 246 | CHECK_LT(argc, INT_MAX); // Check for overflow. | |
| 258 | 247 | args_vals.reserve(argc); | |
@@ -273,26 +262,18 @@ class ProcessWrap : public HandleWrap { | |||
| 273 | 262 | options.args = options_args.data(); | |
| 274 | 263 | } | |
| 275 | 264 | ||
| 276 | - // options.cwd | ||
| 277 | - Local<Value> cwd_v; | ||
| 278 | - if (!js_options->Get(context, env->cwd_string()).ToLocal(&cwd_v)) { | ||
| 279 | - return; | ||
| 280 | - } | ||
| 265 | + // args[2] cwd | ||
| 281 | 266 | node::Utf8Value cwd(env->isolate(), | |
| 282 | - cwd_v->IsString() ? cwd_v : Local<Value>()); | ||
| 267 | + args[2]->IsString() ? args[2] : Local<Value>()); | ||
| 283 | 268 | if (cwd.length() > 0) { | |
| 284 | 269 | options.cwd = *cwd; | |
| 285 | 270 | } | |
| 286 | 271 | ||
| 287 | - // options.env | ||
| 288 | - Local<Value> env_v; | ||
| 289 | - if (!js_options->Get(context, env->env_pairs_string()).ToLocal(&env_v)) { | ||
| 290 | - return; | ||
| 291 | - } | ||
| 272 | + // args[3] envPairs | ||
| 292 | 273 | std::vector<char*> options_env; | |
| 293 | 274 | std::vector<std::string> env_vals; | |
| 294 | - if (env_v->IsArray()) { | ||
| 295 | - Local<Array> env_opt = env_v.As<Array>(); | ||
| 275 | + if (args[3]->IsArray()) { | ||
| 276 | + Local<Array> env_opt = args[3].As<Array>(); | ||
| 296 | 277 | int envc = env_opt->Length(); | |
| 297 | 278 | CHECK_LT(envc, INT_MAX); // Check for overflow. | |
| 298 | 279 | env_vals.reserve(envc); | |
@@ -313,48 +294,31 @@ class ProcessWrap : public HandleWrap { | |||
| 313 | 294 | options.env = options_env.data(); | |
| 314 | 295 | } | |
| 315 | 296 | ||
| 316 | - // options.stdio | ||
| 297 | + // args[4] stdio | ||
| 317 | 298 | std::vector<uv_stdio_container_t> options_stdio; | |
| 318 | - if (ParseStdioOptions(env, js_options, &options_stdio).IsNothing()) { | ||
| 299 | + if (ParseStdioOptions(env, args[4], &options_stdio).IsNothing()) { | ||
| 319 | 300 | return; | |
| 320 | 301 | } | |
| 321 | 302 | options.stdio = options_stdio.data(); | |
| 322 | 303 | options.stdio_count = options_stdio.size(); | |
| 323 | 304 | ||
| 324 | - // options.windowsHide | ||
| 325 | - Local<Value> hide_v; | ||
| 326 | - if (!js_options->Get(context, env->windows_hide_string()) | ||
| 327 | - .ToLocal(&hide_v)) { | ||
| 328 | - return; | ||
| 329 | - } | ||
| 305 | + // args[5] flags (detached, windowsHide, windowsVerbatimArguments) | ||
| 306 | + CHECK(args[5]->IsUint32()); | ||
| 307 | + const uint32_t flags = args[5].As<Uint32>()->Value(); | ||
| 330 | 308 | ||
| 331 | - if (hide_v->IsTrue()) { | ||
| 309 | + if (flags & kProcessFlagWindowsHide) { | ||
| 332 | 310 | options.flags |= UV_PROCESS_WINDOWS_HIDE; | |
| 333 | 311 | } | |
| 334 | 312 | ||
| 335 | 313 | if (env->hide_console_windows()) { | |
| 336 | 314 | options.flags |= UV_PROCESS_WINDOWS_HIDE_CONSOLE; | |
| 337 | 315 | } | |
| 338 | 316 | ||
| 339 | - // options.windows_verbatim_arguments | ||
| 340 | - Local<Value> wva_v; | ||
| 341 | - if (!js_options->Get(context, env->windows_verbatim_arguments_string()) | ||
| 342 | - .ToLocal(&wva_v)) { | ||
| 343 | - return; | ||
| 344 | - } | ||
| 345 | - | ||
| 346 | - if (wva_v->IsTrue()) { | ||
| 317 | + if (flags & kProcessFlagWindowsVerbatimArguments) { | ||
| 347 | 318 | options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; | |
| 348 | 319 | } | |
| 349 | 320 | ||
| 350 | - // options.detached | ||
| 351 | - Local<Value> detached_v; | ||
| 352 | - if (!js_options->Get(context, env->detached_string()) | ||
| 353 | - .ToLocal(&detached_v)) { | ||
| 354 | - return; | ||
| 355 | - } | ||
| 356 | - | ||
| 357 | - if (detached_v->IsTrue()) { | ||
| 321 | + if (flags & kProcessFlagDetached) { | ||
| 358 | 322 | options.flags |= UV_PROCESS_DETACHED; | |
| 359 | 323 | } | |
| 360 | 324 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,6 +18,7 @@ import { MessagingBinding } from './internalBinding/messaging'; | |||
| 18 | 18 | import { OptionsBinding } from './internalBinding/options'; | |
| 19 | 19 | import { OSBinding } from './internalBinding/os'; | |
| 20 | 20 | import { ProcessBinding } from './internalBinding/process'; | |
| 21 | + import { ProcessWrapBinding } from './internalBinding/process_wrap'; | ||
| 21 | 22 | import { SeaBinding } from './internalBinding/sea'; | |
| 22 | 23 | import { SerdesBinding } from './internalBinding/serdes'; | |
| 23 | 24 | import { StringDecoderBinding } from './internalBinding/string_decoder'; | |
@@ -55,6 +56,7 @@ interface InternalBindingMap { | |||
| 55 | 56 | options: OptionsBinding; | |
| 56 | 57 | os: OSBinding; | |
| 57 | 58 | process: ProcessBinding; | |
| 59 | + process_wrap: ProcessWrapBinding; | ||
| 58 | 60 | sea: SeaBinding; | |
| 59 | 61 | serdes: SerdesBinding; | |
| 60 | 62 | string_decoder: StringDecoderBinding; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,43 @@ | |||
| 1 | + import { owner_symbol } from './symbols'; | ||
| 2 | + | ||
| 3 | + declare namespace InternalProcessWrapBinding { | ||
| 4 | + type StdioType = 'ignore' | 'pipe' | 'overlapped' | 'wrap' | 'inherit' | 'fd'; | ||
| 5 | + | ||
| 6 | + interface StdioContainer { | ||
| 7 | + type: StdioType; | ||
| 8 | + handle?: object; | ||
| 9 | + fd?: number; | ||
| 10 | + } | ||
| 11 | + | ||
| 12 | + class Process { | ||
| 13 | + constructor(); | ||
| 14 | + [owner_symbol]?: object; | ||
| 15 | + pid: number; | ||
| 16 | + onexit: (exitCode: number, signalCode: string) => void; | ||
| 17 | + spawn( | ||
| 18 | + file: string, | ||
| 19 | + args: string[] | undefined, | ||
| 20 | + cwd: string | undefined, | ||
| 21 | + envPairs: string[] | undefined, | ||
| 22 | + stdio: StdioContainer[], | ||
| 23 | + flags: number, | ||
| 24 | + uid: number | null | undefined, | ||
| 25 | + gid: number | null | undefined, | ||
| 26 | + ): number; | ||
| 27 | + kill(signal: number): number; | ||
| 28 | + ref(): void; | ||
| 29 | + unref(): void; | ||
| 30 | + close(callback?: () => void): void; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + interface ProcessConstants { | ||
| 34 | + kProcessFlagDetached: number; | ||
| 35 | + kProcessFlagWindowsHide: number; | ||
| 36 | + kProcessFlagWindowsVerbatimArguments: number; | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + export interface ProcessWrapBinding { | ||
| 41 | + Process: typeof InternalProcessWrapBinding.Process; | ||
| 42 | + constants: InternalProcessWrapBinding.ProcessConstants; | ||
| 43 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments