Fix spawn dup ordering - #9578
Merged
Merged
Conversation
The logic here, ported from CRuby, had two different orders in which it could perform the dups. If the parent's state had already been saved, as for forking, the dups should proceed in ascending order of the child descriptors. If the parent's state had not already been saved, as for a non-forking spawn, the dups should proceed in ascending order of the parent descriptors, lest they get overwritten by subsequent dups. The logic in CRuby is very messy, due to splicing both forking and non-forking logic together in the same methods, and the JRuby port went astray here. We captured the parent state, but because we do not fork we did not actually handle that state as thought we were in a forked child. We did, however, proceed to use the order of the child descriptors to indicate the order of the dups, which resulted in `in: STDOUT` seeing and duping the wrong stdout (i.e. whatever stream would eventually be the child's stdout). In the example cases from jruby#9577, this could be the popen pipe (not a terminal), /dev/null (also not a terminal), or whatever was passed to popen via `out:` redirect. In the working case there, that redirect is `out: STDOUT`, accidentally making the correct parent stdout available in the child for the `in:` dup. The fix is to always use the ordering of the input descriptors, since posix_spawn will perform the redirects for us in that order, and we don't want lower descriptors to be overwritten before we have a change to deal with them. Fixes jruby#9577
An issue in JRuby's redirect-ordering logic for popen caused it to overwrite STDOUT before redirecting it, resulting in STDIN getting the wrong source descriptor. As a result, a child `stty` process did not get the controlling terminal. This spec tests that the redirect of STDOUT to STDIN happens before any alteration of the child's STDOUT. See jruby#9577 for details.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The ordering here was leftover from ported CRuby logic and incorrectly did the redirects in reverse order. For
in: STDOUT, this caused any redirect to the child'sSTDOUTto get used for the input of thein:redirect. Because that childSTDOUTwould be a pipe if not otherwise specified, thein:ended up with a non-TTY and broke ourstty-based io-console logic (ruby/io-console#145).Fixes #9577.