-
Notifications
You must be signed in to change notification settings - Fork 30.8k
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
regression: child_process stdin pipe close event not emitted #25131
Comments
The provided test case also emits the following uv error for me, but only after the script is ended, so I presume it comes from the child.
|
hmm, I don't see that. Maybe I didn't compile with assertions enabled. I agree that it should be coming from the child process. You could test by using a Python child instead :)
|
shall I work on this issue. |
Reverting #18701 on master doesn't resolve this issue for me and I guess that's because of 67e2a15. Maybe we could call node/lib/internal/child_process.js Line 390 in 80873ec
rather than passing |
Is this still a problem on e.g. v14? |
@ronag, I just ran the test script with v14.12.0 and it is still broken. |
After the socket is created, we trigger an empty read to make sure we catch stdio events like closing the stdin file descriptor. Otherwise those events will go undetected until the next stream write. Fixes: nodejs#25131
There's been no further discussion or activity on this in quite some time. Is there still stuff to do here? |
Summary
Since #18701 Node.js doesn't emit a close event when a child process closes its stdin pipe. The close is only detected if the parent tries to write to the child's stdin and receives an EPIPE.
The original behaviour is preferable because it allows immediate detection of the close event, rather than waiting for a failed write.
Reproducer
This works as expected in v8.11.4 and fails in all newer versions of v8.x, as well as all v10.x and all v11.x.
Problem detail
As far as I can tell the only way the close event can be emitted is if the
Socket
constructor callsthis.read(0)
. This triggersonStreamRead()
to be called, which doesstream.push(null)
and eventually results in the close event. This is a little weird because stdin isn't a readable stream :)In Node 8.11.4 this worked because
child_process.js:createSocket()
called theSocket
constructor withoptions.readable === undefined
. So theSocket
constructor sees thatoptions.readable !== false
and runsthis.read(0)
In PR #18701
createSocket()
was changed to call theSocket
constructor withoptions.readable === true
. This stopsthis.read(0)
from being called and the close event is not emitted.Hacky solution
This passes the full test suite with a minor change to
test-pipewrap.js
. I haven't raised a PR because I'm sure somebody could think of a better solution. If someone can point me in the right direction I'm happy to try and implement it.Thanks :)
The text was updated successfully, but these errors were encountered: