--- /dev/null
+// 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))
+}
--- /dev/null
+// 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
+}
"context"
"encoding/binary"
"fmt"
+ "internal/syscall/unix"
"internal/testenv"
"internal/testpty"
"os"
"syscall"
"testing"
"time"
- "unsafe"
)
const (
// 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
// 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