]> Cypherpunks repositories - gostls13.git/commitdiff
os/signal: avoid calling ioctl via syscall.Syscall on BSDs
authorJoel Sing <joel@sing.id.au>
Mon, 6 Nov 2023 13:39:27 +0000 (00:39 +1100)
committerJoel Sing <joel@sing.id.au>
Wed, 20 Mar 2024 10:09:15 +0000 (10:09 +0000)
Provide appropriate implementations of internal/syscall/unix.Tcsetpgrp
and use this for runSessionLeader in os/signal/signal_cgo_test.go.
This avoids calling syscall.Syscall with SYS_IOCTL on BSDs.

Updates #59667
Updates #63900

Change-Id: Ifa4696bba9f1eb68e81e7103f030bc254adaf0af
Reviewed-on: https://go-review.googlesource.com/c/go/+/540020
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Joel Sing <joel@sing.id.au>

src/internal/syscall/unix/tcsetpgrp_bsd.go [new file with mode: 0644]
src/internal/syscall/unix/tcsetpgrp_linux.go [new file with mode: 0644]
src/os/signal/signal_cgo_test.go

diff --git a/src/internal/syscall/unix/tcsetpgrp_bsd.go b/src/internal/syscall/unix/tcsetpgrp_bsd.go
new file mode 100644 (file)
index 0000000..bac614d
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+
+package unix
+
+import (
+       "syscall"
+       "unsafe"
+)
+
+//go:linkname ioctlPtr syscall.ioctlPtr
+func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error)
+
+// Note that pgid should really be pid_t, however _C_int (aka int32) is
+// generally equivalent.
+
+func Tcsetpgrp(fd int, pgid int32) (err error) {
+       return ioctlPtr(fd, syscall.TIOCSPGRP, unsafe.Pointer(&pgid))
+}
diff --git a/src/internal/syscall/unix/tcsetpgrp_linux.go b/src/internal/syscall/unix/tcsetpgrp_linux.go
new file mode 100644 (file)
index 0000000..be208d9
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+       "syscall"
+       "unsafe"
+)
+
+// Note that pgid should really be pid_t, however _C_int (aka int32) is
+// generally equivalent.
+
+func Tcsetpgrp(fd int, pgid int32) (err error) {
+       _, _, errno := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCSPGRP), uintptr(unsafe.Pointer(&pgid)), 0, 0, 0)
+       if errno != 0 {
+               return errno
+       }
+       return nil
+}
index 0aaf38c221decd6b9bf2e305f4b7630b5179d5a3..bc6f030d5f14cfd87dad9da4c60cd865e3ca1cf9 100644 (file)
@@ -14,6 +14,7 @@ import (
        "context"
        "encoding/binary"
        "fmt"
+       "internal/syscall/unix"
        "internal/testenv"
        "internal/testpty"
        "os"
@@ -23,7 +24,6 @@ import (
        "syscall"
        "testing"
        "time"
-       "unsafe"
 )
 
 const (
@@ -304,9 +304,8 @@ func runSessionLeader(t *testing.T, pause time.Duration) {
 
                // Take TTY.
                pgrp := int32(syscall.Getpgrp()) // assume that pid_t is int32
-               _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, ptyFD, syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&pgrp)))
-               if errno != 0 {
-                       return fmt.Errorf("error setting tty process group: %w", errno)
+               if err := unix.Tcsetpgrp(ptyFD, pgrp); err != nil {
+                       return fmt.Errorf("error setting tty process group: %w", err)
                }
 
                // Give the kernel time to potentially wake readers and have
@@ -315,9 +314,8 @@ func runSessionLeader(t *testing.T, pause time.Duration) {
 
                // Give TTY back.
                pid := int32(cmd.Process.Pid) // assume that pid_t is int32
-               _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, ptyFD, syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&pid)))
-               if errno != 0 {
-                       return fmt.Errorf("error setting tty process group back: %w", errno)
+               if err := unix.Tcsetpgrp(ptyFD, pid); err != nil {
+                       return fmt.Errorf("error setting tty process group back: %w", err)
                }
 
                // Report that we are done and SIGCONT can be sent. Note that