...

Source file src/syscall/syscall_unix.go

Documentation: syscall

		 1  // Copyright 2009 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  
		 8  package syscall
		 9  
		10  import (
		11  	"internal/itoa"
		12  	"internal/oserror"
		13  	"internal/race"
		14  	"internal/unsafeheader"
		15  	"runtime"
		16  	"sync"
		17  	"unsafe"
		18  )
		19  
		20  var (
		21  	Stdin	= 0
		22  	Stdout = 1
		23  	Stderr = 2
		24  )
		25  
		26  const (
		27  	darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8
		28  	netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
		29  )
		30  
		31  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
		32  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
		33  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
		34  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
		35  
		36  // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
		37  func clen(n []byte) int {
		38  	for i := 0; i < len(n); i++ {
		39  		if n[i] == 0 {
		40  			return i
		41  		}
		42  	}
		43  	return len(n)
		44  }
		45  
		46  // Mmap manager, for use by operating system-specific implementations.
		47  
		48  type mmapper struct {
		49  	sync.Mutex
		50  	active map[*byte][]byte // active mappings; key is last byte in mapping
		51  	mmap	 func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
		52  	munmap func(addr uintptr, length uintptr) error
		53  }
		54  
		55  func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
		56  	if length <= 0 {
		57  		return nil, EINVAL
		58  	}
		59  
		60  	// Map the requested memory.
		61  	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
		62  	if errno != nil {
		63  		return nil, errno
		64  	}
		65  
		66  	// Use unsafe to turn addr into a []byte.
		67  	var b []byte
		68  	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
		69  	hdr.Data = unsafe.Pointer(addr)
		70  	hdr.Cap = length
		71  	hdr.Len = length
		72  
		73  	// Register mapping in m and return it.
		74  	p := &b[cap(b)-1]
		75  	m.Lock()
		76  	defer m.Unlock()
		77  	m.active[p] = b
		78  	return b, nil
		79  }
		80  
		81  func (m *mmapper) Munmap(data []byte) (err error) {
		82  	if len(data) == 0 || len(data) != cap(data) {
		83  		return EINVAL
		84  	}
		85  
		86  	// Find the base of the mapping.
		87  	p := &data[cap(data)-1]
		88  	m.Lock()
		89  	defer m.Unlock()
		90  	b := m.active[p]
		91  	if b == nil || &b[0] != &data[0] {
		92  		return EINVAL
		93  	}
		94  
		95  	// Unmap the memory and update m.
		96  	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
		97  		return errno
		98  	}
		99  	delete(m.active, p)
	 100  	return nil
	 101  }
	 102  
	 103  // An Errno is an unsigned number describing an error condition.
	 104  // It implements the error interface. The zero Errno is by convention
	 105  // a non-error, so code to convert from Errno to error should use:
	 106  //	err = nil
	 107  //	if errno != 0 {
	 108  //		err = errno
	 109  //	}
	 110  //
	 111  // Errno values can be tested against error values from the os package
	 112  // using errors.Is. For example:
	 113  //
	 114  //	_, _, err := syscall.Syscall(...)
	 115  //	if errors.Is(err, fs.ErrNotExist) ...
	 116  type Errno uintptr
	 117  
	 118  func (e Errno) Error() string {
	 119  	if 0 <= int(e) && int(e) < len(errors) {
	 120  		s := errors[e]
	 121  		if s != "" {
	 122  			return s
	 123  		}
	 124  	}
	 125  	return "errno " + itoa.Itoa(int(e))
	 126  }
	 127  
	 128  func (e Errno) Is(target error) bool {
	 129  	switch target {
	 130  	case oserror.ErrPermission:
	 131  		return e == EACCES || e == EPERM
	 132  	case oserror.ErrExist:
	 133  		return e == EEXIST || e == ENOTEMPTY
	 134  	case oserror.ErrNotExist:
	 135  		return e == ENOENT
	 136  	}
	 137  	return false
	 138  }
	 139  
	 140  func (e Errno) Temporary() bool {
	 141  	return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout()
	 142  }
	 143  
	 144  func (e Errno) Timeout() bool {
	 145  	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
	 146  }
	 147  
	 148  // Do the interface allocations only once for common
	 149  // Errno values.
	 150  var (
	 151  	errEAGAIN error = EAGAIN
	 152  	errEINVAL error = EINVAL
	 153  	errENOENT error = ENOENT
	 154  )
	 155  
	 156  // errnoErr returns common boxed Errno values, to prevent
	 157  // allocations at runtime.
	 158  func errnoErr(e Errno) error {
	 159  	switch e {
	 160  	case 0:
	 161  		return nil
	 162  	case EAGAIN:
	 163  		return errEAGAIN
	 164  	case EINVAL:
	 165  		return errEINVAL
	 166  	case ENOENT:
	 167  		return errENOENT
	 168  	}
	 169  	return e
	 170  }
	 171  
	 172  // A Signal is a number describing a process signal.
	 173  // It implements the os.Signal interface.
	 174  type Signal int
	 175  
	 176  func (s Signal) Signal() {}
	 177  
	 178  func (s Signal) String() string {
	 179  	if 0 <= s && int(s) < len(signals) {
	 180  		str := signals[s]
	 181  		if str != "" {
	 182  			return str
	 183  		}
	 184  	}
	 185  	return "signal " + itoa.Itoa(int(s))
	 186  }
	 187  
	 188  func Read(fd int, p []byte) (n int, err error) {
	 189  	n, err = read(fd, p)
	 190  	if race.Enabled {
	 191  		if n > 0 {
	 192  			race.WriteRange(unsafe.Pointer(&p[0]), n)
	 193  		}
	 194  		if err == nil {
	 195  			race.Acquire(unsafe.Pointer(&ioSync))
	 196  		}
	 197  	}
	 198  	if msanenabled && n > 0 {
	 199  		msanWrite(unsafe.Pointer(&p[0]), n)
	 200  	}
	 201  	return
	 202  }
	 203  
	 204  func Write(fd int, p []byte) (n int, err error) {
	 205  	if race.Enabled {
	 206  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
	 207  	}
	 208  	if faketime && (fd == 1 || fd == 2) {
	 209  		n = faketimeWrite(fd, p)
	 210  		if n < 0 {
	 211  			n, err = 0, errnoErr(Errno(-n))
	 212  		}
	 213  	} else {
	 214  		n, err = write(fd, p)
	 215  	}
	 216  	if race.Enabled && n > 0 {
	 217  		race.ReadRange(unsafe.Pointer(&p[0]), n)
	 218  	}
	 219  	if msanenabled && n > 0 {
	 220  		msanRead(unsafe.Pointer(&p[0]), n)
	 221  	}
	 222  	return
	 223  }
	 224  
	 225  // For testing: clients can set this flag to force
	 226  // creation of IPv6 sockets to return EAFNOSUPPORT.
	 227  var SocketDisableIPv6 bool
	 228  
	 229  type Sockaddr interface {
	 230  	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
	 231  }
	 232  
	 233  type SockaddrInet4 struct {
	 234  	Port int
	 235  	Addr [4]byte
	 236  	raw	RawSockaddrInet4
	 237  }
	 238  
	 239  type SockaddrInet6 struct {
	 240  	Port	 int
	 241  	ZoneId uint32
	 242  	Addr	 [16]byte
	 243  	raw		RawSockaddrInet6
	 244  }
	 245  
	 246  type SockaddrUnix struct {
	 247  	Name string
	 248  	raw	RawSockaddrUnix
	 249  }
	 250  
	 251  func Bind(fd int, sa Sockaddr) (err error) {
	 252  	ptr, n, err := sa.sockaddr()
	 253  	if err != nil {
	 254  		return err
	 255  	}
	 256  	return bind(fd, ptr, n)
	 257  }
	 258  
	 259  func Connect(fd int, sa Sockaddr) (err error) {
	 260  	ptr, n, err := sa.sockaddr()
	 261  	if err != nil {
	 262  		return err
	 263  	}
	 264  	return connect(fd, ptr, n)
	 265  }
	 266  
	 267  func Getpeername(fd int) (sa Sockaddr, err error) {
	 268  	var rsa RawSockaddrAny
	 269  	var len _Socklen = SizeofSockaddrAny
	 270  	if err = getpeername(fd, &rsa, &len); err != nil {
	 271  		return
	 272  	}
	 273  	return anyToSockaddr(&rsa)
	 274  }
	 275  
	 276  func GetsockoptInt(fd, level, opt int) (value int, err error) {
	 277  	var n int32
	 278  	vallen := _Socklen(4)
	 279  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
	 280  	return int(n), err
	 281  }
	 282  
	 283  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
	 284  	var rsa RawSockaddrAny
	 285  	var len _Socklen = SizeofSockaddrAny
	 286  	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
	 287  		return
	 288  	}
	 289  	if rsa.Addr.Family != AF_UNSPEC {
	 290  		from, err = anyToSockaddr(&rsa)
	 291  	}
	 292  	return
	 293  }
	 294  
	 295  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
	 296  	ptr, n, err := to.sockaddr()
	 297  	if err != nil {
	 298  		return err
	 299  	}
	 300  	return sendto(fd, p, flags, ptr, n)
	 301  }
	 302  
	 303  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
	 304  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
	 305  }
	 306  
	 307  func SetsockoptInt(fd, level, opt int, value int) (err error) {
	 308  	var n = int32(value)
	 309  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
	 310  }
	 311  
	 312  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
	 313  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
	 314  }
	 315  
	 316  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
	 317  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
	 318  }
	 319  
	 320  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
	 321  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
	 322  }
	 323  
	 324  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
	 325  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
	 326  }
	 327  
	 328  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
	 329  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
	 330  }
	 331  
	 332  func SetsockoptString(fd, level, opt int, s string) (err error) {
	 333  	var p unsafe.Pointer
	 334  	if len(s) > 0 {
	 335  		p = unsafe.Pointer(&[]byte(s)[0])
	 336  	}
	 337  	return setsockopt(fd, level, opt, p, uintptr(len(s)))
	 338  }
	 339  
	 340  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
	 341  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
	 342  }
	 343  
	 344  func Socket(domain, typ, proto int) (fd int, err error) {
	 345  	if domain == AF_INET6 && SocketDisableIPv6 {
	 346  		return -1, EAFNOSUPPORT
	 347  	}
	 348  	fd, err = socket(domain, typ, proto)
	 349  	return
	 350  }
	 351  
	 352  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
	 353  	var fdx [2]int32
	 354  	err = socketpair(domain, typ, proto, &fdx)
	 355  	if err == nil {
	 356  		fd[0] = int(fdx[0])
	 357  		fd[1] = int(fdx[1])
	 358  	}
	 359  	return
	 360  }
	 361  
	 362  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
	 363  	if race.Enabled {
	 364  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
	 365  	}
	 366  	return sendfile(outfd, infd, offset, count)
	 367  }
	 368  
	 369  var ioSync int64
	 370  

View as plain text