1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
6// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
7
8package unix
9
10import (
11	"runtime"
12	"unsafe"
13)
14
15// ioctl itself should not be exposed directly, but additional get/set
16// functions for specific types are permissible.
17
18// IoctlSetInt performs an ioctl operation which sets an integer value
19// on fd, using the specified request number.
20func IoctlSetInt(fd int, req uint, value int) error {
21	return ioctl(fd, req, uintptr(value))
22}
23
24// IoctlSetPointerInt performs an ioctl operation which sets an
25// integer value on fd, using the specified request number. The ioctl
26// argument is called with a pointer to the integer value, rather than
27// passing the integer value directly.
28func IoctlSetPointerInt(fd int, req uint, value int) error {
29	v := int32(value)
30	return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
31}
32
33// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
34//
35// To change fd's window size, the req argument should be TIOCSWINSZ.
36func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
37	// TODO: if we get the chance, remove the req parameter and
38	// hardcode TIOCSWINSZ.
39	err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
40	runtime.KeepAlive(value)
41	return err
42}
43
44// IoctlSetTermios performs an ioctl on fd with a *Termios.
45//
46// The req value will usually be TCSETA or TIOCSETA.
47func IoctlSetTermios(fd int, req uint, value *Termios) error {
48	// TODO: if we get the chance, remove the req parameter.
49	err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
50	runtime.KeepAlive(value)
51	return err
52}
53
54// IoctlGetInt performs an ioctl operation which gets an integer value
55// from fd, using the specified request number.
56//
57// A few ioctl requests use the return value as an output parameter;
58// for those, IoctlRetInt should be used instead of this function.
59func IoctlGetInt(fd int, req uint) (int, error) {
60	var value int
61	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
62	return value, err
63}
64
65func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
66	var value Winsize
67	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
68	return &value, err
69}
70
71func IoctlGetTermios(fd int, req uint) (*Termios, error) {
72	var value Termios
73	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
74	return &value, err
75}
76