Browse Source

Expose original argv as process.execArgv for cluster and child_process.fork()

v0.9.1-release
Micheil Smith 13 years ago
committed by isaacs
parent
commit
19fd5301bf
  1. 8
      lib/child_process.js
  2. 4
      lib/cluster.js
  3. 50
      src/node.cc

8
lib/child_process.js

@ -165,7 +165,7 @@ function nop() { }
exports.fork = function(modulePath /*, args, options*/) { exports.fork = function(modulePath /*, args, options*/) {
// Get options and args arguments. // Get options and args arguments.
var options, args; var options, args, execArgv;
if (Array.isArray(arguments[1])) { if (Array.isArray(arguments[1])) {
args = arguments[1]; args = arguments[1];
options = arguments[2] || {}; options = arguments[2] || {};
@ -174,9 +174,9 @@ exports.fork = function(modulePath /*, args, options*/) {
options = arguments[1] || {}; options = arguments[1] || {};
} }
// Copy args and add modulePath // Prepare arguments for fork:
args = args.slice(0); execArgv = options.execArgv || process.execArgv;
args.unshift(modulePath); args = execArgv.concat([modulePath], args);
// Don't allow stdinStream and customFds since a stdin channel will be used // Don't allow stdinStream and customFds since a stdin channel will be used
if (options.stdinStream) { if (options.stdinStream) {

4
lib/cluster.js

@ -91,6 +91,7 @@ cluster.setupMaster = function(options) {
// Set settings object // Set settings object
settings = cluster.settings = { settings = cluster.settings = {
exec: options.exec || process.argv[1], exec: options.exec || process.argv[1],
execArgv: options.execArgv || process.execArgv,
args: options.args || process.argv.slice(2), args: options.args || process.argv.slice(2),
silent: options.silent || false silent: options.silent || false
}; };
@ -274,7 +275,8 @@ function Worker(customEnv) {
// fork worker // fork worker
this.process = fork(settings.exec, settings.args, { this.process = fork(settings.exec, settings.args, {
'env': envCopy, 'env': envCopy,
'silent': settings.silent 'silent': settings.silent,
'execArgv': settings.execArgv
}); });
} else { } else {
this.process = process; this.process = process;

50
src/node.cc

@ -2126,6 +2126,15 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
// assign it // assign it
process->Set(String::NewSymbol("argv"), arguments); process->Set(String::NewSymbol("argv"), arguments);
// process.execArgv
Local<Array> execArgv = Array::New(option_end_index - 1);
for (j = 1, i = 0; j < option_end_index; j++, i++) {
execArgv->Set(Integer::New(i), String::New(argv[j]));
}
// assign it
process->Set(String::NewSymbol("execArgv"), execArgv);
// create process.env // create process.env
Local<ObjectTemplate> envTemplate = ObjectTemplate::New(); Local<ObjectTemplate> envTemplate = ObjectTemplate::New();
envTemplate->SetNamedPropertyHandler(EnvGetter, envTemplate->SetNamedPropertyHandler(EnvGetter,
@ -2713,10 +2722,45 @@ void EmitExit(v8::Handle<v8::Object> process_l) {
} }
} }
static char **copy_argv(int argc, char **argv) {
size_t strlen_sum;
char **argv_copy;
char *argv_data;
size_t len;
int i;
strlen_sum = 0;
for(i = 0; i < argc; i++) {
strlen_sum += strlen(argv[i]) + 1;
}
argv_copy = (char **) malloc(sizeof(char *) * (argc + 1) + strlen_sum);
if (!argv_copy) {
return NULL;
}
argv_data = (char *) argv_copy + sizeof(char *) * (argc + 1);
for(i = 0; i < argc; i++) {
argv_copy[i] = argv_data;
len = strlen(argv[i]) + 1;
memcpy(argv_data, argv[i], len);
argv_data += len;
}
argv_copy[argc] = NULL;
return argv_copy;
}
int Start(int argc, char *argv[]) { int Start(int argc, char *argv[]) {
// Logic to duplicate argv as Init() modifies arguments
// that are passed into it.
char **argv_copy = copy_argv(argc, argv);
// This needs to run *before* V8::Initialize() // This needs to run *before* V8::Initialize()
argv = Init(argc, argv); // Use copy here as to not modify the original argv:
Init(argc, argv_copy);
V8::Initialize(); V8::Initialize();
Persistent<Context> context; Persistent<Context> context;
@ -2728,6 +2772,7 @@ int Start(int argc, char *argv[]) {
Persistent<Context> context = Context::New(); Persistent<Context> context = Context::New();
Context::Scope context_scope(context); Context::Scope context_scope(context);
// Use original argv, as we're just copying values out of it.
Handle<Object> process_l = SetupProcessObject(argc, argv); Handle<Object> process_l = SetupProcessObject(argc, argv);
v8_typed_array::AttachBindings(context->Global()); v8_typed_array::AttachBindings(context->Global());
@ -2753,6 +2798,9 @@ int Start(int argc, char *argv[]) {
V8::Dispose(); V8::Dispose();
#endif // NDEBUG #endif // NDEBUG
// Clean up the copy:
free(argv_copy);
return 0; return 0;
} }

Loading…
Cancel
Save