You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
stdout, stderr and stdin are all Duplex streams but documentation states otherwise #9201
The process.stderr property returns a Writable stream equivalent to or associated with stderr (fd 2).
...
The process.stdin property returns a Readable stream equivalent to or associated with stdin (fd 0).
...
The process.stdout property returns a Writable stream equivalent to or associated with stdout (fd 1).
But the actual Implementation is of a Duplex stream -
Using a unidirectional stream seems like the obvious choice but if this is not possible for some reason the documentation should be fixed.
This is a bit more annoying with node 4.x (I checked on v4.6.1) since Duplex stream do not extend Writable ones so this will actually evaluate to false -
process.stdoutinstanceofStream.Writable
Documentation doesn't mention stream type for v4.x but if the type cannot be changed from Duplex maybe it should mention that since this can cause some confusion
FWIW the reason for this is that the process.stdin/stdout/stderr are actually net.Socket objects, which are Duplex streams. You can see this by inspecting process.stdin.constructor for example.
Using a unidirectional stream seems like the obvious choice but if this is not possible for some reason the documentation should be fixed.
We currently don’t actually check whether the FDs 0, 1, 2 are readable/writable, and there’s no reason why they can’t be both (e.g. for TTYs or in child processes spawned by node), so keeping it to a generic socket is probably okay.
(This also means that the .readable and .writable properties of stdio streams may be lying. Sigh.)
@addaleax I don't know enough about node or linux internals but I didn't think a process could write to its own stdin.
I understand that with child process you want to write into the child.stdin but from the child process,stdin should still only be readable no ?
I don't know enough about node or linux internals but I didn't think a process could write to its own stdin.
If you’re e.g. just running node some-file.js in a POSIX terminal, the FDs 0, 1 and 2 will be indistinguishable references to the TTY – you can read from and write to any of them, each time with the same effect (which is one of the reasons why stderr and stdout can interleave in your terminal, btw). And r/w to any of them is technically supported on Node’s side, too, because the TTY streams inherit from net.Socket. As you may guess, this breaks down as soon as you redirect stdout to a file, for example.
I understand that with child process you want to write into the child.stdin but from the child process,stdin should still only be readable no ?
When you specify pipe to child_process.spawn on POSIX, you get a socket pair (there’s been a thread in nodejs/help with a bit more detail).
I guess it’s weird that you can write to stdin, but it may start to make sense once you think about it – Node doesn’t really give you any way to specify whether the child process should see the readable end or the writable end of a pipe.
Actually, I'm not sure if writing to process.stdin still works the way it used to. It looks like commit 9ae1a61 from March last year put a stop to that. It's arguably a kind of regression because a snippet like below used to work in older versions of node:
@addaleax So maybe it's a good ides to have them as a unidirection
streams and throwing an error if someone tries to write to stdin or read from stdout.
So if anyone makes such a mistake it will be caught quickly.
If someone has an actual need to write to stdin I guess they can always create a custom stream using the file descriptor.
Though I don't know if this is actually possible with the current net.Socket implementation
@yonjah I think I generally agree with you, but more in a “maybe Node should have done this differently from the beginning” kind of way. To break this now does not sound like it’s worth the breakage to me, even if there is only a very small amount of it.
Activity
mscdex commentedon Oct 20, 2016
FWIW the reason for this is that the
process.stdin/stdout/stderrare actuallynet.Socketobjects, which are Duplex streams. You can see this by inspectingprocess.stdin.constructorfor example.Fishrock123 commentedon Oct 20, 2016
I'd say this is probably just a bug in the inheritance chain of Duplex streams prior to v6.8.0.
addaleax commentedon Oct 20, 2016
We currently don’t actually check whether the FDs 0, 1, 2 are readable/writable, and there’s no reason why they can’t be both (e.g. for TTYs or in child processes spawned by node), so keeping it to a generic
socketis probably okay.(This also means that the
.readableand.writableproperties of stdio streams may be lying. Sigh.)princejwesley commentedon Oct 20, 2016
@addaleax I doubt that, In the REPL case (#9189), underlying Input stream is read-only in windows.
addaleax commentedon Oct 20, 2016
Yeah, I wouldn’t count the Windows console as a real TTY. ;)
yonjah commentedon Oct 20, 2016
@addaleax I don't know enough about node or linux internals but I didn't think a process could write to its own stdin.
I understand that with child process you want to write into the child.stdin but from the child process,stdin should still only be readable no ?
addaleax commentedon Oct 20, 2016
If you’re e.g. just running
node some-file.jsin a POSIX terminal, the FDs 0, 1 and 2 will be indistinguishable references to the TTY – you can read from and write to any of them, each time with the same effect (which is one of the reasons whystderrandstdoutcan interleave in your terminal, btw). And r/w to any of them is technically supported on Node’s side, too, because the TTY streams inherit fromnet.Socket. As you may guess, this breaks down as soon as you redirect stdout to a file, for example.When you specify
pipetochild_process.spawnon POSIX, you get a socket pair (there’s been a thread in nodejs/help with a bit more detail).I guess it’s weird that you can write to
stdin, but it may start to make sense once you think about it – Node doesn’t really give you any way to specify whether the child process should see the readable end or the writable end of apipe.bnoordhuis commentedon Oct 20, 2016
Actually, I'm not sure if writing to
process.stdinstill works the way it used to. It looks like commit 9ae1a61 from March last year put a stop to that. It's arguably a kind of regression because a snippet like below used to work in older versions of node:I'll file an issue.
EDIT: Fixed copy/paste error in example.
yonjah commentedon Oct 21, 2016
@bnoordhuis @addaleax Can you give a semi real example where this might actually be used ?
addaleax commentedon Oct 21, 2016
@yonjah I’ve never seen something like that in the wild, no (well, at least not done intentionally 😄).
I’d say it’s more that there’s no real reason to treat the stdio FDs different from other FDs.
yonjah commentedon Oct 22, 2016
@addaleax So maybe it's a good ides to have them as a unidirection
streams and throwing an error if someone tries to write to
stdinor read fromstdout.So if anyone makes such a mistake it will be caught quickly.
If someone has an actual need to write to stdin I guess they can always create a custom stream using the file descriptor.
Though I don't know if this is actually possible with the current
net.Socketimplementationprincejwesley commentedon Oct 22, 2016
@yonjah we write to stdin in unit tests.
addaleax commentedon Oct 23, 2016
@yonjah I think I generally agree with you, but more in a “maybe Node should have done this differently from the beginning” kind of way. To break this now does not sound like it’s worth the breakage to me, even if there is only a very small amount of it.
3 remaining items
doc: stdout, stderr and stdin are all Duplex streams but documentatio…
fhinkel commentedon Mar 27, 2017
Thanks, landed in 1005b1d
doc: stdout/err/in are all Duplex streams
doc: stdout/err/in are all Duplex streams
doc: stdout/err/in are all Duplex streams
doc: stdout/err/in are all Duplex streams
doc: stdout/err/in are all Duplex streams