-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
child_process: set stdin properties when exec
ed
#2336
Conversation
f6efdee
to
166a05e
Compare
166a05e
to
1d0a4ec
Compare
When a child process is created, the `stdin` will not have `isTTY`, `isRaw` and `setRawMode` properties. Because, `uv_guess_handle` in `guessHandleType` call returns `PIPE` for fd 0. So, we create a `net.Socket` and return. But normally it will return `TTY` and we create `tty.ReadStream` and return where all those properties are properly set. This path explicitly sets the above mentioned properties on the returned socket object. Fixes: nodejs#2333 PR-URL: nodejs#2336
1d0a4ec
to
5d70af8
Compare
Hmm, I'm just getting 4x undefined still after this patch on OS X. What OS are you on? |
@silverwind Oh, I am using Ubuntu 14.04.2 |
What does my test case print for you? I'll try this on linux too, building will take a while though. |
Your testcase prints |
Shouldn't it like print those properties? (parent prints child's stdout, which logs them) :) |
Oh wait I'm dumb. I need to supply the built binary to |
@silverwind You meant after the fix? It prints |
Yeah, works as expected now. Let's see what the CI says. |
@silverwind It fails only in Windows, as of now, but that is because the splitting with |
Also breaks the REPL it seems. |
Oh, which OS? I couldn't see any REPL failures till now. |
OS X:
|
Ah, it breaks in Ubuntu 14.04.02 as well. Till now they were checking if Interface.prototype._setRawMode = function(mode) {
if (typeof this.input.setRawMode === 'function') {
return this.input.setRawMode(mode);
}
}; Should this be considered as a breaking change and the repl should also be fixed? Because, Socket objects can not be considered as raw devices AFAIK. |
You could wrap in a I'm not understanding yet why you call it a Socket. Isn't stdin basically just a readable stream from fd 0? |
Not if |
Hmm, wouldn't it be better to set the missing properties just in the PIPE case then? Seems to be safer to me. |
Something like this maybe: diff --git a/src/node.js b/src/node.js
index dfe3599..347d424 100644
--- a/src/node.js
+++ b/src/node.js
@@ -649,8 +649,9 @@
var tty_wrap = process.binding('tty_wrap');
var fd = 0;
+ var handleType = tty_wrap.guessHandleType(fd);
- switch (tty_wrap.guessHandleType(fd)) {
+ switch (handleType) {
case 'TTY':
var tty = NativeModule.require('tty');
stdin = new tty.ReadStream(fd, {
@@ -717,11 +718,14 @@
stdin._handle.readStop();
});
- stdin.isTTY = true;
- stdin.isRaw = false;
- stdin.setRawMode = function setRawMode() {
- throw new Error('Not a raw device');
- };
+ // set the missing TTY properties when spawned through child_process.exec
+ if (handleType === 'PIPE') {
+ stdin.isTTY = true;
+ stdin.isRaw = false;
+ stdin.setRawMode = function setRawMode() {
+ throw new Error('Not a raw device');
+ };
+ }
return stdin;
}); |
But the properties will be still missing for the NET case, right? |
Yeah. I'm not even sure what a NET handle would be. A quick look at |
I think we're confusing something. It's |
Hmmm I am on mobile now. I'll also go through the code once, with your inputs, in the morning. |
Sure, here's what I propose: diff --git a/src/node.js b/src/node.js
index dfe3599..7fe4c48 100644
--- a/src/node.js
+++ b/src/node.js
@@ -666,7 +666,6 @@
break;
case 'PIPE':
- case 'TCP':
var net = NativeModule.require('net');
// It could be that process has been started with an IPC channel
@@ -688,6 +687,13 @@
}
// Make sure the stdin can't be `.end()`-ed
stdin._writableState.ended = true;
+
+ // Add missing TTY properties
+ stdin.isTTY = false;
+ stdin.isRaw = false;
+ stdin.setRawMode = function setRawMode() {
+ throw new Error('Not a raw device');
+ };
break;
default:
@@ -717,12 +723,6 @@
stdin._handle.readStop();
});
- stdin.isTTY = true;
- stdin.isRaw = false;
- stdin.setRawMode = function setRawMode() {
- throw new Error('Not a raw device');
- };
-
return stdin;
}); |
I'm pondering if it's actually worth to do the |
stdin.isRaw = false; | ||
stdin.setRawMode = function setRawMode() { | ||
throw new Error('Not a raw device'); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks incorrect to me. .isTTY
should only be true when stdin refers to a real tty, not when it's a file/pipe/socket/etc.
You could wrap it in a if (!process.stdin.hasOwnProperty('isTTY')) { ... }
block, although that feels kind of icky (and the fact that .isTTY
is an own property is something of an implementation detail, so if (!('isTTY' in process.stdin)) { .. }
is probably more correct.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, stdin.isTTY
should definitely be false in the PIPE case. I corrected that in my latest diff suggestion.
The whole change is more of a correctness thing. Most scripts do just if (stdin.isTTY)
, in which case it wouldn't matter if it's undefined or false.
The FreeBSD machine times out, not sure if relevant (can't check right now). |
@thefourtheye I'll do a PR which supersedes this one if you don't mind. |
@silverwind Oh no problem :-) I ll close this. |
Hey guys, we are having an error at devtool related to |
@rafaelcastrocouto How about you file a new issue instead of hijacking an existing pull request? |
sorry @bnoordhuis ... in my defense I just wanted some advice and I really don't think this is a node issue. Since the subject of this issue seems very related to my problem I just thought someone could easily point how to solve it. I'll keep looking ... thx and sorry again |
@rafaelcastrocouto If you have a general support question, try https://github.com/nodejs/help/issues. This issue tracker is pretty high-volume, that's why we try to keep it focused. |
Thx a lot @bnoordhuis ... nodejs/help#105 |
When a child process is created, the
stdin
will not haveisTTY
,isRaw
andsetRawMode
properties. Because,uv_guess_handle
inguessHandleType
call returnsPIPE
for fd 0. So, we create anet.Socket
and return. But normally it will returnTTY
and we createtty.ReadStream
and return where all those properties are properly set.This path explicitly sets the above mentioned properties on the returned
socket object.
Fixes: #2333