Skip to content

Commit 202dd83

Browse files
committed
Add setsid option to child_process
1 parent 9da75f3 commit 202dd83

4 files changed

Lines changed: 35 additions & 7 deletions

File tree

doc/api/child_processes.markdown

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,15 @@ The third argument is used to specify additional options, which defaults to:
5959

6060
{ cwd: undefined,
6161
env: process.env,
62-
customFds: [-1, -1, -1] }
62+
customFds: [-1, -1, -1],
63+
setsid: false
64+
}
6365

6466
`cwd` allows you to specify the working directory from which the process is spawned.
6567
Use `env` to specify environment variables that will be visible to the new process.
6668
With `customFds` it is possible to hook up the new process' [stdin, stout, stderr] to
67-
existing streams; `-1` means that a new stream should be created.
69+
existing streams; `-1` means that a new stream should be created. `setsid`,
70+
if set true, will cause the subprocess to be run in a new session.
6871

6972
Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit code:
7073

lib/child_process.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ exports.execFile = function(file /* args, options, callback */) {
2525
timeout: 0,
2626
maxBuffer: 200 * 1024,
2727
killSignal: 'SIGTERM',
28+
setsid: false,
2829
cwd: null,
2930
env: null };
3031
var args, optionArg, callback;
@@ -184,19 +185,21 @@ ChildProcess.prototype.kill = function(sig) {
184185
ChildProcess.prototype.spawn = function(path, args, options, customFds) {
185186
args = args || [];
186187

187-
var cwd, env;
188+
var cwd, env, setuid;
188189
if (!options || options.cwd === undefined &&
189190
options.env === undefined &&
190191
options.customFds === undefined) {
191192
// Deprecated API: (path, args, options, env, customFds)
192193
cwd = '';
193194
env = options || process.env;
194195
customFds = customFds || [-1, -1, -1];
196+
setuid = false;
195197
} else {
196198
// Recommended API: (path, args, options)
197199
cwd = options.cwd || '';
198200
env = options.env || process.env;
199201
customFds = options.customFds || [-1, -1, -1];
202+
setuid = options.setuid ? true : false;
200203
}
201204

202205
var envPairs = [];
@@ -206,7 +209,12 @@ ChildProcess.prototype.spawn = function(path, args, options, customFds) {
206209
envPairs.push(key + '=' + env[key]);
207210
}
208211

209-
var fds = this._internal.spawn(path, args, cwd, envPairs, customFds);
212+
var fds = this._internal.spawn(path,
213+
args,
214+
cwd,
215+
envPairs,
216+
customFds,
217+
setuid);
210218
this.fds = fds;
211219

212220
if (customFds[0] === -1 || customFds[0] === undefined) {

src/node_child_process.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,15 @@ Handle<Value> ChildProcess::Spawn(const Arguments& args) {
150150
}
151151
}
152152

153+
int do_setuid = false;
154+
if (args[5]->IsBoolean()) {
155+
do_setuid = args[5]->BooleanValue();
156+
}
157+
158+
153159
int fds[3];
154160

155-
int r = child->Spawn(argv[0], argv, cwd, env, fds, custom_fds);
161+
int r = child->Spawn(argv[0], argv, cwd, env, fds, custom_fds, do_setuid);
156162

157163
for (i = 0; i < argv_length; i++) free(argv[i]);
158164
delete [] argv;
@@ -226,7 +232,8 @@ int ChildProcess::Spawn(const char *file,
226232
const char *cwd,
227233
char **env,
228234
int stdio_fds[3],
229-
int custom_fds[3]) {
235+
int custom_fds[3],
236+
bool do_setuid) {
230237
HandleScope scope;
231238
assert(pid_ == -1);
232239
assert(!ev_is_active(&child_watcher_));
@@ -267,6 +274,10 @@ int ChildProcess::Spawn(const char *file,
267274
return -4;
268275

269276
case 0: // Child.
277+
if (do_setuid && setsid() < 0) {
278+
perror("setuid");
279+
}
280+
270281
if (custom_fds[0] == -1) {
271282
close(stdin_pipe[1]); // close write end
272283
dup2(stdin_pipe[0], STDIN_FILENO);

src/node_child_process.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ class ChildProcess : ObjectWrap {
5858
// are readable.
5959
// The user of this class has responsibility to close these pipes after
6060
// the child process exits.
61-
int Spawn(const char *file, char *const argv[], const char *cwd, char **env, int stdio_fds[3], int custom_fds[3]);
61+
int Spawn(const char *file,
62+
char *const argv[],
63+
const char *cwd,
64+
char **env,
65+
int stdio_fds[3],
66+
int custom_fds[3],
67+
bool do_setuid);
6268

6369
// Simple syscall wrapper. Does not disable the watcher. onexit will be
6470
// called still.

0 commit comments

Comments
 (0)