I am opening the /dev/ptmx
file on MacOS 14.2.1
. When I open this file,it by default opens in non-blocking mode, I am not sure why because I do not specify O_NONBLOCK
flag while opening it. When I try to read from /dev/ptmx
I get an EAGAIN
error. I even invoke the Fd()
method on this file to get the file descriptor, the source code of Fd()
puts the file on blocking mode, but in spite of that I get the EAGAIN
error. I have found two fixes but I am unable to understand why these fixes work.
Go Version: 1.22
Code which gives me EAGAIN
error
ptmx, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR, 0)
if err != nil {
panic(err)
}
err = Unlockpt(ptmx) // this function call the `ptmx.Fd()` method
if err != nil {
fmt.Println("unlock err", err)
return
}
name, err := Ptsname(ptmx) // this function call the `ptmx.Fd()` method
if err != nil {
fmt.Println("err", err)
return
}
go func() {
_, err = io.Copy(os.Stdout, ptmx)
if err != nil {
// EAGAIN error is received here
fmt.Println("copy err", err)
}
close(done)
}()
Fix1: Open the file in O_NONBLOCK mode, somehow this sets the file in blocking mode
ptmx, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NONBLOCK, 0)
// this works and I do not get the `EAGAIN` error on read
go func() {
_, err = io.Copy(os.Stdout, ptmx)
if err != nil {
// NO EGAIN error and works fine
fmt.Println("copy err", err)
}
close(done)
}()
Fix2: Invoke the syscall.SetNonblock(int(ptmx.Fd()), false)
This also works because I am manually setting the file into blocking mode.