Closed gcrtnst closed 11 months ago
@gcrtnst, thank you for the detailed report! I have encountered a similar problem with blocking Read() and your mention of side effects in (*os.File).Fd()
had saved me a significant amount of time.
I have submitted a PR (#167) to fix this problem, but until it gets merged you may be interested in a workaround. You can manually reset file descriptor to non-blocking mode:
--- issue162/demo-fail.go
+++ issue162/demo-ok.go
@@ -3,6 +3,7 @@
import (
"fmt"
"os"
+ "syscall"
"time"
"github.com/creack/pty"
@@ -17,6 +18,11 @@
defer ptmx.Close()
defer pts.Close()
+ err = syscall.SetNonblock(int(ptmx.Fd()), true)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to unblock ptmx: %v\n", err)
+ }
+
err = ptmx.SetDeadline(time.Now().Add(5 * time.Second))
if err != nil {
fmt.Fprintf(os.Stderr, "error: set deadline: %v\n", err)
Of course, this will only work until you make another call to Fd()
through pty library, though it's often good enough for my use cases.
Closed with #167
Run the following code:
Expected behavior: The code exits after 5 seconds and the output following
Actual behavior: The code does not exit forever, it blocks on the
ptmx.Read
call and does not output anything to the stdout/stderr.The cause of the issue is that "github.com/creack/pty" package calls
(*os.File).Fd
internally, which disables the SetDeadline method on Unix systems. Using(*os.File).SyscallConn
instead may solve this issue.This other issue posted on StackOverflow may have the same cause.
I reproduced this issue on Linux, but it may happen on other platforms.