Repository navigation
detached child_process doesn't inherit stdio #3596
Description
Activity
- addedchild_processIssues and PRs related to the child_process subsystem.Issues and PRs related to the child_process subsystem.
on Oct 30, 2015 { detached: true }is sugar forsetsid(2), meaning it disconnects from the controlling tty. Does that answer you question? If not, can you post a complete example with expected and actual output?@bnoordhuis is this expected behavior? With Node 5 on OS X, and the following code:
process.stdout; require('child_process').spawn('ls', [], { stdio: 'inherit', detached: true });
Nothing is printed. However, if I comment out the
process.stdouton the first line, thenlsoutput is displayed.Reacted by Aleksey Timchenko/cc @indutny - I'm guessing it's related to OS X's broken kqueue support for special files and libuv's workaround. I can reproduce on OS X but it works fine on Linux, FWIW.
The only explanation that I have is that reopening stdout as
/dev/ttysomehow interferes with it.Gosh, it is twice as odd, considering that piping the output like this:
node test.js | lessworks just fine in both cases. I suspect some OS X oddness atm...And of course it is related to the reopening of
/dev/ttyin libuv: https://github.com/libuv/libuv/blob/25506bb33156f15e27a837979773264dfe8d06be/src/unix/tty.c#L64-L87 . Removing that branch fixes the problem.I think there is some fishy stuff with the current session and the way
/dev/ttyattaches to it on OS X, but I am not yet quite sure what exactly is happening there.It looks like for a child process
writereturnsEIO:write(0x1, "\0", 0x1) = -1 Err#5@wonnage may I ask you to give a try to this patch?
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 571f8cd..c02c750 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -283,8 +283,10 @@ static void uv__process_child_init(const uv_process_options_t* options, int use_fd; int fd; - if (options->flags & UV_PROCESS_DETACHED) + if (options->flags & UV_PROCESS_DETACHED) { + setpgid(getpid(), getpid()); setsid(); + } /* First duplicate low numbered fds, since it's not safe to duplicate them, * they could get replaced. Example: swapping stdout and stderr; without
I suspect that this is an OS X kernel bug and that for some reason
pg->pg_jobcis0ifsetsid()is called alone.Gosh, I have figured it out. The actual device behind
/dev/ttylives inbsd/kern/tty_tty.c. The thing about this device is that it always looks up the tty using current proc's session. So when you create a new session, it doesn't have any tty assigned to it, and all syscalls on it will result in EIO error.I'll need some time to think if there is any workaround for this.
I failed at it miserably :( Submitted Apple bugreport # 23994737
Hey! sorry i've been inactive on this thread - switched jobs and no longer working on the code that produced this error in the first place :)
handwaving through my ignorance of unix internals a bit, but is this a correct summary of the issue:
we start with a parent process hooked up to a tty
setsid makes the new process lose controlling terminal (/dev/tty isn't backed up by anything)afterwards, piping
node test.js | lessworks because stdout is going to stdin ofless;lessis in the same session as parent and writes to controlling tty just fine, and we get output.however, if stdout is a tty (
node test.js), the uv change you linked attempts to reopen /dev/tty, but at this point /dev/tty doesn't point anywhere in the new process (due to OSX). is there some way to save a reference to correct tty and pass that to the child process in uv_tty_init when calling uv__open_cloexec?@wonnage I believe piping works because it is not using tty at all, it is using pipes.
- addedmacosIssues and PRs related to the macOS platform.Issues and PRs related to the macOS platform.
on Mar 4, 2016 @indutny would you mind sharing the apple bug report on open radar?
Curious if this is fixed with libuv 1.9.x
Seeing something very similar with
stdinon Windows and Node v6.7.1 anyone know the root of this and if there is another bug not linked here that might contain what the fix was?cc/ @chalkers
The following snippet of code prints the child process' output if detached is true, and doesn't if it's false:
This part of the docs seems relevant:
Which seems to imply that inheriting these streams is supported. Not sure if this is just me misreading the docs or...