Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Merged
spikecurtis merged 1 commit intomainfromspike/macos-pty-race
Apr 25, 2023
Merged
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletionspty/start_other.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,25 @@ func startPty(cmd *exec.Cmd, opt ...StartOption) (retPTY *otherPty, proc Process
}
return nil, nil, xerrors.Errorf("start: %w", err)
}
// 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, reading from the process output
// will block until we close our TTY.
if err := opty.tty.Close(); err != nil {
_ = cmd.Process.Kill()
return nil, nil, xerrors.Errorf("close tty: %w", err)
if runtime.GOOS == "linux" {
Copy link
Member

Choose a reason for hiding this comment

The 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 checkingtcgetattr on master to decide if we keep both ends open but no idea hire reliable that is:https://stackoverflow.com/questions/23458160/final-output-on-slave-pty-is-lost-if-it-was-not-closed-in-parent-why/25123701#comment36273878_23458160

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The 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.

mafredri reacted with thumbs up emoji
// 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.
}
opty.tty = nil // remove so we don't attempt to close it again.
oProcess := &otherProcess{
pty: opty.pty,
cmd: cmd,
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp