Skip to content

Commit 9246436

Browse files
authored
Merge pull request #215 from WeidiDeng/unsafe-pointer
Avoid calls to (*os.File).Fd() when calling ioctl
2 parents edfbf75 + e47170d commit 9246436

15 files changed

Lines changed: 41 additions & 42 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ go get github.com/creack/pty
1010

1111
## Examples
1212

13-
Note that those examples are for demonstration purpose only, to showcase how to use the library. They are not meant to be used in any kind of production environment. If you want to **set deadlines to work** and `Close()` **interrupting** `Read()` on the returned `*os.File`, you will need to call `syscall.SetNonblock` manually.
13+
Note that those examples are for demonstration purpose only, to showcase how to use the library. They are not meant to be used in any kind of production environment.
1414

1515
### Command
1616

io_test.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"os"
1010
"runtime"
1111
"sync"
12-
"syscall"
1312
"testing"
1413
"time"
1514
)
@@ -30,9 +29,6 @@ var glTestFdLock sync.Mutex
3029
//nolint:paralleltest // Potential in (*os.File).Fd().
3130
func TestReadDeadline(t *testing.T) {
3231
ptmx, success := prepare(t)
33-
if err := syscall.SetNonblock(int(ptmx.Fd()), true); err != nil {
34-
t.Fatalf("Error: set non block: %s", err)
35-
}
3632

3733
if err := ptmx.SetDeadline(time.Now().Add(timeout / 10)); err != nil {
3834
if errors.Is(err, os.ErrNoDeadline) {
@@ -62,9 +58,6 @@ func TestReadDeadline(t *testing.T) {
6258
//nolint:paralleltest // Potential in (*os.File).Fd().
6359
func TestReadClose(t *testing.T) {
6460
ptmx, success := prepare(t)
65-
if err := syscall.SetNonblock(int(ptmx.Fd()), true); err != nil {
66-
t.Fatalf("Error: set non block: %s", err)
67-
}
6861

6962
go func() {
7063
time.Sleep(timeout / 10)

ioctl.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33

44
package pty
55

6-
import "os"
6+
import (
7+
"os"
8+
"unsafe"
9+
)
710

8-
func ioctl(f *os.File, cmd, ptr uintptr) error {
9-
return ioctlInner(f.Fd(), cmd, ptr) // Fall back to blocking io.
10-
}
11-
12-
// NOTE: Unused. Keeping for reference.
13-
func ioctlNonblock(f *os.File, cmd, ptr uintptr) error {
11+
func ioctl(f *os.File, cmd uintptr, ptr unsafe.Pointer) error {
1412
sc, e := f.SyscallConn()
1513
if e != nil {
1614
return ioctlInner(f.Fd(), cmd, ptr) // Fall back to blocking io (old behavior).

ioctl_inner.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@
33

44
package pty
55

6-
import "syscall"
6+
import (
7+
"syscall"
8+
"unsafe"
9+
)
710

811
// Local syscall const values.
912
const (
1013
TIOCGWINSZ = syscall.TIOCGWINSZ
1114
TIOCSWINSZ = syscall.TIOCSWINSZ
1215
)
1316

14-
func ioctlInner(fd, cmd, ptr uintptr) error {
15-
_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
17+
func ioctlInner(fd, cmd uintptr, ptr unsafe.Pointer) error {
18+
_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, uintptr(ptr))
1619
if e != 0 {
1720
return e
1821
}

ioctl_legacy.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33

44
package pty
55

6-
import "os"
6+
import (
7+
"os"
8+
"unsafe"
9+
)
710

8-
func ioctl(f *os.File, cmd, ptr uintptr) error {
11+
func ioctl(f *os.File, cmd uintptr, ptr unsafe.Pointer) error {
912
return ioctlInner(f.Fd(), cmd, ptr) // fall back to blocking io (old behavior)
1013
}

ioctl_solaris.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ type strioctl struct {
4040
// Defined in asm_solaris_amd64.s.
4141
func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
4242

43-
func ioctlInner(fd, cmd, ptr uintptr) error {
44-
if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, fd, cmd, ptr, 0, 0, 0); errno != 0 {
43+
func ioctlInner(fd, cmd uintptr, ptr unsafe.Pointer) error {
44+
if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, fd, cmd, uintptr(ptr), 0, 0, 0); errno != 0 {
4545
return errno
4646
}
4747
return nil

ioctl_unsupported.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33

44
package pty
55

6+
import "unsafe"
7+
68
const (
79
TIOCGWINSZ = 0
810
TIOCSWINSZ = 0
911
)
1012

11-
func ioctlInner(fd, cmd, ptr uintptr) error {
13+
func ioctlInner(fd, cmd uintptr, ptr unsafe.Pointer) error {
1214
return ErrUnsupported
1315
}

pty_darwin.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func open() (pty, tty *os.File, err error) {
4646
func ptsname(f *os.File) (string, error) {
4747
n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME))
4848

49-
err := ioctl(f, syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
49+
err := ioctl(f, syscall.TIOCPTYGNAME, unsafe.Pointer(&n[0]))
5050
if err != nil {
5151
return "", err
5252
}
@@ -60,9 +60,9 @@ func ptsname(f *os.File) (string, error) {
6060
}
6161

6262
func grantpt(f *os.File) error {
63-
return ioctl(f, syscall.TIOCPTYGRANT, 0)
63+
return ioctl(f, syscall.TIOCPTYGRANT, unsafe.Pointer(nil))
6464
}
6565

6666
func unlockpt(f *os.File) error {
67-
return ioctl(f, syscall.TIOCPTYUNLK, 0)
67+
return ioctl(f, syscall.TIOCPTYUNLK, unsafe.Pointer(nil))
6868
}

pty_dragonfly.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func unlockpt(f *os.File) error {
5555
}
5656

5757
func isptmaster(f *os.File) (bool, error) {
58-
err := ioctl(f, syscall.TIOCISPTMASTER, 0)
58+
err := ioctl(f, syscall.TIOCISPTMASTER, unsafe.Pointer(nil))
5959
return err == nil, err
6060
}
6161

@@ -68,7 +68,7 @@ func ptsname(f *os.File) (string, error) {
6868
name := make([]byte, _C_SPECNAMELEN)
6969
fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}}
7070

71-
err := ioctl(f, ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa)))
71+
err := ioctl(f, ioctl_FIODNAME, unsafe.Pointer(&fa))
7272
if err != nil {
7373
return "", err
7474
}

pty_freebsd.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func open() (pty, tty *os.File, err error) {
4545
}
4646

4747
func isptmaster(f *os.File) (bool, error) {
48-
err := ioctl(f, syscall.TIOCPTMASTER, 0)
48+
err := ioctl(f, syscall.TIOCPTMASTER, unsafe.Pointer(nil))
4949
return err == nil, err
5050
}
5151

@@ -68,7 +68,7 @@ func ptsname(f *os.File) (string, error) {
6868
buf = make([]byte, n)
6969
arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))}
7070
)
71-
if err := ioctl(f, ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil {
71+
if err := ioctl(f, ioctlFIODGNAME, unsafe.Pointer(&arg)); err != nil {
7272
return "", err
7373
}
7474

0 commit comments

Comments
 (0)