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

4
lib/cluster.js

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

50
src/node.cc

@ -2126,6 +2126,15 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
// assign it
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
Local<ObjectTemplate> envTemplate = ObjectTemplate::New();
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[]) {
// 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()
argv = Init(argc, argv);
// Use copy here as to not modify the original argv:
Init(argc, argv_copy);
V8::Initialize();
Persistent<Context> context;
@ -2728,6 +2772,7 @@ int Start(int argc, char *argv[]) {
Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
// Use original argv, as we're just copying values out of it.
Handle<Object> process_l = SetupProcessObject(argc, argv);
v8_typed_array::AttachBindings(context->Global());
@ -2753,6 +2798,9 @@ int Start(int argc, char *argv[]) {
V8::Dispose();
#endif // NDEBUG
// Clean up the copy:
free(argv_copy);
return 0;
}

Loading…
Cancel
Save