- Notifications
You must be signed in to change notification settings - Fork1.1k
fix: macOS pty race with dropped output#7278
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -50,17 +50,25 @@ func startPty(cmd *exec.Cmd, opt ...StartOption) (retPTY *otherPty, proc Process | ||
| } | ||
| return nil, nil, xerrors.Errorf("start: %w", err) | ||
| } | ||
| if runtime.GOOS == "linux" { | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I wonder if, down the line, this might give us a bad time trying to support other OSs (e.g. BSD variants). I found a SO post that confirms Darwin like behavior on FreeBSD (8.2) as well, but apparently the behavior may be closer to Linux in 10.0 which could mean we may block on output copy. https://stackoverflow.com/a/25123701 A comment mentions checking ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. It definitely might! But, the unit test we have should fail if the BSD version we intend to support acts like Linux and doesn't get the close, so I guess we'll just cross that bridge if we come to it. | ||
| // Now that we've started the command, and passed the TTY to it, close | ||
| // our file so that the other process has the only open file to the TTY. | ||
| // Once the process closes the TTY (usually on exit), there will be no | ||
| // open references and the OS kernel returns an error when trying to | ||
| // read or write to our PTY end. Without this (on Linux), reading from | ||
| // the process output will block until we close our TTY. | ||
| // | ||
| // Note that on darwin, reads on the PTY don't block even if we keep the | ||
| // TTY file open, and keeping it open seems to prevent race conditions | ||
| // where we lose output. Couldn't find official documentation | ||
| // confirming this, but I did find a thread of someone else's | ||
| // observations: https://developer.apple.com/forums/thread/663632 | ||
| if err := opty.tty.Close(); err != nil { | ||
| _ = cmd.Process.Kill() | ||
| return nil, nil, xerrors.Errorf("close tty: %w", err) | ||
| } | ||
| opty.tty = nil // remove so we don't attempt to close it again. | ||
| } | ||
| oProcess := &otherProcess{ | ||
| pty: opty.pty, | ||
| cmd: cmd, | ||