Skip to content

Unnecessary process.args/env coping when spawning a child? #45868

Closed
@ywave620

Description

@ywave620

The following TODO arouses my interest. Why we need to deep copy args and env to heap? The parent can not access or even modify the copy of them in the child once uv_spawn succeed, in case it failed, libuv does not(and has no reason) to touch them.

Code to prepare uv_process_options_t before call uv_spawn() in the implementation of child_process.spawn :

node/src/process_wrap.cc

Lines 178 to 204 in b3f5a41

// TODO(bnoordhuis) is this possible to do without mallocing ?
// options.file
Local<Value> file_v =
js_options->Get(context, env->file_string()).ToLocalChecked();
CHECK(file_v->IsString());
node::Utf8Value file(env->isolate(), file_v);
options.file = *file;
// options.args
Local<Value> argv_v =
js_options->Get(context, env->args_string()).ToLocalChecked();
if (!argv_v.IsEmpty() && argv_v->IsArray()) {
Local<Array> js_argv = argv_v.As<Array>();
int argc = js_argv->Length();
CHECK_GT(argc + 1, 0); // Check for overflow.
// Heap allocate to detect errors. +1 is for nullptr.
options.args = new char*[argc + 1];
for (int i = 0; i < argc; i++) {
node::Utf8Value arg(env->isolate(),
js_argv->Get(context, i).ToLocalChecked());
options.args[i] = strdup(*arg);
CHECK_NOT_NULL(options.args[i]);
}
options.args[argc] = nullptr;
}

Code to prepare uv_process_options_t before call uv_spawn() in the implementation of child_process.spawnSync :

node/src/spawn_sync.cc

Lines 755 to 765 in b3f5a41

Local<Value> js_file =
js_options->Get(context, env()->file_string()).ToLocalChecked();
if (!CopyJsString(js_file, &file_buffer_).To(&r)) return Nothing<int>();
if (r < 0) return Just(r);
uv_process_options_.file = file_buffer_;
Local<Value> js_args =
js_options->Get(context, env()->args_string()).ToLocalChecked();
if (!CopyJsStringArray(js_args, &args_buffer_).To(&r)) return Nothing<int>();
if (r < 0) return Just(r);
uv_process_options_.args = reinterpret_cast<char**>(args_buffer_);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions