// Copyright 2009 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 unix

package syscall

import (
	errorspkg 
	
	
	
	
	
	
	
)

var (
	Stdin  = 0
	Stdout = 1
	Stderr = 2
)

const (
	darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8
	netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
)

// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
func clen( []byte) int {
	if  := bytealg.IndexByte(, 0);  != -1 {
		return 
	}
	return len()
}

// Mmap manager, for use by operating system-specific implementations.

type mmapper struct {
	sync.Mutex
	active map[*byte][]byte // active mappings; key is last byte in mapping
	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
	munmap func(addr uintptr, length uintptr) error
}

func ( *mmapper) ( int,  int64,  int,  int,  int) ( []byte,  error) {
	if  <= 0 {
		return nil, EINVAL
	}

	// Map the requested memory.
	,  := .mmap(0, uintptr(), , , , )
	if  != nil {
		return nil, 
	}

	// Use unsafe to turn addr into a []byte.
	 := unsafe.Slice((*byte)(unsafe.Pointer()), )

	// Register mapping in m and return it.
	 := &[cap()-1]
	.Lock()
	defer .Unlock()
	.active[] = 
	return , nil
}

func ( *mmapper) ( []byte) ( error) {
	if len() == 0 || len() != cap() {
		return EINVAL
	}

	// Find the base of the mapping.
	 := &[cap()-1]
	.Lock()
	defer .Unlock()
	 := .active[]
	if  == nil || &[0] != &[0] {
		return EINVAL
	}

	// Unmap the memory and update m.
	if  := .munmap(uintptr(unsafe.Pointer(&[0])), uintptr(len()));  != nil {
		return 
	}
	delete(.active, )
	return nil
}

// An Errno is an unsigned number describing an error condition.
// It implements the error interface. The zero Errno is by convention
// a non-error, so code to convert from Errno to error should use:
//
//	err = nil
//	if errno != 0 {
//		err = errno
//	}
//
// Errno values can be tested against error values using errors.Is.
// For example:
//
//	_, _, err := syscall.Syscall(...)
//	if errors.Is(err, fs.ErrNotExist) ...
type Errno uintptr

func ( Errno) () string {
	if 0 <= int() && int() < len(errors) {
		 := errors[]
		if  != "" {
			return 
		}
	}
	return "errno " + itoa.Itoa(int())
}

func ( Errno) ( error) bool {
	switch  {
	case oserror.ErrPermission:
		return  == EACCES ||  == EPERM
	case oserror.ErrExist:
		return  == EEXIST ||  == ENOTEMPTY
	case oserror.ErrNotExist:
		return  == ENOENT
	case errorspkg.ErrUnsupported:
		return  == ENOSYS ||  == ENOTSUP ||  == EOPNOTSUPP
	}
	return false
}

func ( Errno) () bool {
	return  == EINTR ||  == EMFILE ||  == ENFILE || .Timeout()
}

func ( Errno) () bool {
	return  == EAGAIN ||  == EWOULDBLOCK ||  == ETIMEDOUT
}

// Do the interface allocations only once for common
// Errno values.
var (
	errEAGAIN error = EAGAIN
	errEINVAL error = EINVAL
	errENOENT error = ENOENT
)

// errnoErr returns common boxed Errno values, to prevent
// allocations at runtime.
func errnoErr( Errno) error {
	switch  {
	case 0:
		return nil
	case EAGAIN:
		return errEAGAIN
	case EINVAL:
		return errEINVAL
	case ENOENT:
		return errENOENT
	}
	return 
}

// A Signal is a number describing a process signal.
// It implements the os.Signal interface.
type Signal int

func ( Signal) () {}

func ( Signal) () string {
	if 0 <=  && int() < len(signals) {
		 := signals[]
		if  != "" {
			return 
		}
	}
	return "signal " + itoa.Itoa(int())
}

func ( int,  []byte) ( int,  error) {
	,  = read(, )
	if race.Enabled {
		if  > 0 {
			race.WriteRange(unsafe.Pointer(&[0]), )
		}
		if  == nil {
			race.Acquire(unsafe.Pointer(&ioSync))
		}
	}
	if msanenabled &&  > 0 {
		msanWrite(unsafe.Pointer(&[0]), )
	}
	if asanenabled &&  > 0 {
		asanWrite(unsafe.Pointer(&[0]), )
	}
	return
}

func ( int,  []byte) ( int,  error) {
	if race.Enabled {
		race.ReleaseMerge(unsafe.Pointer(&ioSync))
	}
	if faketime && ( == 1 ||  == 2) {
		 = faketimeWrite(, )
		if  < 0 {
			,  = 0, errnoErr(Errno(-))
		}
	} else {
		,  = write(, )
	}
	if race.Enabled &&  > 0 {
		race.ReadRange(unsafe.Pointer(&[0]), )
	}
	if msanenabled &&  > 0 {
		msanRead(unsafe.Pointer(&[0]), )
	}
	if asanenabled &&  > 0 {
		asanRead(unsafe.Pointer(&[0]), )
	}
	return
}

func ( int,  []byte,  int64) ( int,  error) {
	,  = pread(, , )
	if race.Enabled {
		if  > 0 {
			race.WriteRange(unsafe.Pointer(&[0]), )
		}
		if  == nil {
			race.Acquire(unsafe.Pointer(&ioSync))
		}
	}
	if msanenabled &&  > 0 {
		msanWrite(unsafe.Pointer(&[0]), )
	}
	if asanenabled &&  > 0 {
		asanWrite(unsafe.Pointer(&[0]), )
	}
	return
}

func ( int,  []byte,  int64) ( int,  error) {
	if race.Enabled {
		race.ReleaseMerge(unsafe.Pointer(&ioSync))
	}
	,  = pwrite(, , )
	if race.Enabled &&  > 0 {
		race.ReadRange(unsafe.Pointer(&[0]), )
	}
	if msanenabled &&  > 0 {
		msanRead(unsafe.Pointer(&[0]), )
	}
	if asanenabled &&  > 0 {
		asanRead(unsafe.Pointer(&[0]), )
	}
	return
}

// For testing: clients can set this flag to force
// creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool

type Sockaddr interface {
	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
}

type SockaddrInet4 struct {
	Port int
	Addr [4]byte
	raw  RawSockaddrInet4
}

type SockaddrInet6 struct {
	Port   int
	ZoneId uint32
	Addr   [16]byte
	raw    RawSockaddrInet6
}

type SockaddrUnix struct {
	Name string
	raw  RawSockaddrUnix
}

func ( int,  Sockaddr) ( error) {
	, ,  := .sockaddr()
	if  != nil {
		return 
	}
	return bind(, , )
}

func ( int,  Sockaddr) ( error) {
	, ,  := .sockaddr()
	if  != nil {
		return 
	}
	return connect(, , )
}

func ( int) ( Sockaddr,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	if  = getpeername(, &, &);  != nil {
		return
	}
	return anyToSockaddr(&)
}

func (, ,  int) ( int,  error) {
	var  int32
	 := _Socklen(4)
	 = getsockopt(, , , unsafe.Pointer(&), &)
	return int(), 
}

func ( int,  []byte,  int) ( int,  Sockaddr,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	if ,  = recvfrom(, , , &, &);  != nil {
		return
	}
	if .Addr.Family != AF_UNSPEC {
		,  = anyToSockaddr(&)
	}
	return
}

func recvfromInet4( int,  []byte,  int,  *SockaddrInet4) ( int,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	if ,  = recvfrom(, , , &, &);  != nil {
		return
	}
	 := (*RawSockaddrInet4)(unsafe.Pointer(&))
	 := (*[2]byte)(unsafe.Pointer(&.Port))
	.Port = int([0])<<8 + int([1])
	.Addr = .Addr
	return
}

func recvfromInet6( int,  []byte,  int,  *SockaddrInet6) ( int,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	if ,  = recvfrom(, , , &, &);  != nil {
		return
	}
	 := (*RawSockaddrInet6)(unsafe.Pointer(&))
	 := (*[2]byte)(unsafe.Pointer(&.Port))
	.Port = int([0])<<8 + int([1])
	.ZoneId = .Scope_id
	.Addr = .Addr
	return
}

func recvmsgInet4( int, ,  []byte,  int,  *SockaddrInet4) (,  int,  int,  error) {
	var  RawSockaddrAny
	, , ,  = recvmsgRaw(, , , , &)
	if  != nil {
		return
	}
	 := (*RawSockaddrInet4)(unsafe.Pointer(&))
	 := (*[2]byte)(unsafe.Pointer(&.Port))
	.Port = int([0])<<8 + int([1])
	.Addr = .Addr
	return
}

func recvmsgInet6( int, ,  []byte,  int,  *SockaddrInet6) (,  int,  int,  error) {
	var  RawSockaddrAny
	, , ,  = recvmsgRaw(, , , , &)
	if  != nil {
		return
	}
	 := (*RawSockaddrInet6)(unsafe.Pointer(&))
	 := (*[2]byte)(unsafe.Pointer(&.Port))
	.Port = int([0])<<8 + int([1])
	.ZoneId = .Scope_id
	.Addr = .Addr
	return
}

func ( int, ,  []byte,  int) (,  int,  int,  Sockaddr,  error) {
	var  RawSockaddrAny
	, , ,  = recvmsgRaw(, , , , &)
	// source address is only specified if the socket is unconnected
	if .Addr.Family != AF_UNSPEC {
		,  = anyToSockaddr(&)
	}
	return
}

func ( int, ,  []byte,  Sockaddr,  int) ( error) {
	_,  = SendmsgN(, , , , )
	return
}

func ( int, ,  []byte,  Sockaddr,  int) ( int,  error) {
	var  unsafe.Pointer
	var  _Socklen
	if  != nil {
		, ,  = .sockaddr()
		if  != nil {
			return 0, 
		}
	}
	return sendmsgN(, , , , , )
}

func sendmsgNInet4( int, ,  []byte,  *SockaddrInet4,  int) ( int,  error) {
	, ,  := .sockaddr()
	if  != nil {
		return 0, 
	}
	return sendmsgN(, , , , , )
}

func sendmsgNInet6( int, ,  []byte,  *SockaddrInet6,  int) ( int,  error) {
	, ,  := .sockaddr()
	if  != nil {
		return 0, 
	}
	return sendmsgN(, , , , , )
}

func sendtoInet4( int,  []byte,  int,  *SockaddrInet4) ( error) {
	, ,  := .sockaddr()
	if  != nil {
		return 
	}
	return sendto(, , , , )
}

func sendtoInet6( int,  []byte,  int,  *SockaddrInet6) ( error) {
	, ,  := .sockaddr()
	if  != nil {
		return 
	}
	return sendto(, , , , )
}

func ( int,  []byte,  int,  Sockaddr) ( error) {
	var (
		   unsafe.Pointer
		 _Socklen
	)
	if  != nil {
		, ,  = .sockaddr()
		if  != nil {
			return 
		}
	}
	return sendto(, , , , )
}

func (, ,  int,  byte) ( error) {
	return setsockopt(, , , unsafe.Pointer(&), 1)
}

func (, ,  int,  int) ( error) {
	var  = int32()
	return setsockopt(, , , unsafe.Pointer(&), 4)
}

func (, ,  int,  [4]byte) ( error) {
	return setsockopt(, , , unsafe.Pointer(&[0]), 4)
}

func (, ,  int,  *IPMreq) ( error) {
	return setsockopt(, , , unsafe.Pointer(), SizeofIPMreq)
}

func (, ,  int,  *IPv6Mreq) ( error) {
	return setsockopt(, , , unsafe.Pointer(), SizeofIPv6Mreq)
}

func (, ,  int,  *ICMPv6Filter) error {
	return setsockopt(, , , unsafe.Pointer(), SizeofICMPv6Filter)
}

func (, ,  int,  *Linger) ( error) {
	return setsockopt(, , , unsafe.Pointer(), SizeofLinger)
}

func (, ,  int,  string) ( error) {
	var  unsafe.Pointer
	if len() > 0 {
		 = unsafe.Pointer(&[]byte()[0])
	}
	return setsockopt(, , , , uintptr(len()))
}

func (, ,  int,  *Timeval) ( error) {
	return setsockopt(, , , unsafe.Pointer(), unsafe.Sizeof(*))
}

func (, ,  int) ( int,  error) {
	if  == AF_INET6 && SocketDisableIPv6 {
		return -1, EAFNOSUPPORT
	}
	,  = socket(, , )
	return
}

func (, ,  int) ( [2]int,  error) {
	var  [2]int32
	 = socketpair(, , , &)
	if  == nil {
		[0] = int([0])
		[1] = int([1])
	}
	return
}

func ( int,  int,  *int64,  int) ( int,  error) {
	if race.Enabled {
		race.ReleaseMerge(unsafe.Pointer(&ioSync))
	}
	return sendfile(, , , )
}

var ioSync int64