package syscall
import (
errorspkg "errors"
"internal/asan"
"internal/bytealg"
"internal/itoa"
"internal/msan"
"internal/oserror"
"internal/race"
"runtime"
"sync"
"unsafe"
)
var (
Stdin = 0
Stdout = 1
Stderr = 2
)
const (
darwin64Bit = (runtime .GOOS == "darwin" || runtime .GOOS == "ios" ) && sizeofPtr == 8
netbsd32Bit = runtime .GOOS == "netbsd" && sizeofPtr == 4
)
func clen(n []byte ) int {
if i := bytealg .IndexByte (n , 0 ); i != -1 {
return i
}
return len (n )
}
type mmapper struct {
sync .Mutex
active map [*byte ][]byte
mmap func (addr, length uintptr , prot, flags, fd int , offset int64 ) (uintptr , error )
munmap func (addr uintptr , length uintptr ) error
}
func (m *mmapper ) Mmap (fd int , offset int64 , length int , prot int , flags int ) (data []byte , err error ) {
if length <= 0 {
return nil , EINVAL
}
addr , errno := m .mmap (0 , uintptr (length ), prot , flags , fd , offset )
if errno != nil {
return nil , errno
}
b := unsafe .Slice ((*byte )(unsafe .Pointer (addr )), length )
p := &b [cap (b )-1 ]
m .Lock ()
defer m .Unlock ()
m .active [p ] = b
return b , nil
}
func (m *mmapper ) Munmap (data []byte ) (err error ) {
if len (data ) == 0 || len (data ) != cap (data ) {
return EINVAL
}
p := &data [cap (data )-1 ]
m .Lock ()
defer m .Unlock ()
b := m .active [p ]
if b == nil || &b [0 ] != &data [0 ] {
return EINVAL
}
if errno := m .munmap (uintptr (unsafe .Pointer (&b [0 ])), uintptr (len (b ))); errno != nil {
return errno
}
delete (m .active , p )
return nil
}
type Errno uintptr
func (e Errno ) Error () string {
if 0 <= int (e ) && int (e ) < len (errors ) {
s := errors [e ]
if s != "" {
return s
}
}
return "errno " + itoa .Itoa (int (e ))
}
func (e Errno ) Is (target error ) bool {
switch target {
case oserror .ErrPermission :
return e == EACCES || e == EPERM
case oserror .ErrExist :
return e == EEXIST || e == ENOTEMPTY
case oserror .ErrNotExist :
return e == ENOENT
case errorspkg .ErrUnsupported :
return e == ENOSYS || e == ENOTSUP || e == EOPNOTSUPP
}
return false
}
func (e Errno ) Temporary () bool {
return e == EINTR || e == EMFILE || e == ENFILE || e .Timeout ()
}
func (e Errno ) Timeout () bool {
return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
}
var (
errEAGAIN error = EAGAIN
errEINVAL error = EINVAL
errENOENT error = ENOENT
)
func errnoErr(e Errno ) error {
switch e {
case 0 :
return nil
case EAGAIN :
return errEAGAIN
case EINVAL :
return errEINVAL
case ENOENT :
return errENOENT
}
return e
}
type Signal int
func (s Signal ) Signal () {}
func (s Signal ) String () string {
if 0 <= s && int (s ) < len (signals ) {
str := signals [s ]
if str != "" {
return str
}
}
return "signal " + itoa .Itoa (int (s ))
}
func Read (fd int , p []byte ) (n int , err error ) {
n , err = read (fd , p )
if race .Enabled {
if n > 0 {
race .WriteRange (unsafe .Pointer (&p [0 ]), n )
}
if err == nil {
race .Acquire (unsafe .Pointer (&ioSync ))
}
}
if msan .Enabled && n > 0 {
msan .Write (unsafe .Pointer (&p [0 ]), uintptr (n ))
}
if asan .Enabled && n > 0 {
asan .Write (unsafe .Pointer (&p [0 ]), uintptr (n ))
}
return
}
func Write (fd int , p []byte ) (n int , err error ) {
if race .Enabled {
race .ReleaseMerge (unsafe .Pointer (&ioSync ))
}
if faketime && (fd == 1 || fd == 2 ) {
n = faketimeWrite (fd , p )
if n < 0 {
n , err = 0 , errnoErr (Errno (-n ))
}
} else {
n , err = write (fd , p )
}
if race .Enabled && n > 0 {
race .ReadRange (unsafe .Pointer (&p [0 ]), n )
}
if msan .Enabled && n > 0 {
msan .Read (unsafe .Pointer (&p [0 ]), uintptr (n ))
}
if asan .Enabled && n > 0 {
asan .Read (unsafe .Pointer (&p [0 ]), uintptr (n ))
}
return
}
func Pread (fd int , p []byte , offset int64 ) (n int , err error ) {
n , err = pread (fd , p , offset )
if race .Enabled {
if n > 0 {
race .WriteRange (unsafe .Pointer (&p [0 ]), n )
}
if err == nil {
race .Acquire (unsafe .Pointer (&ioSync ))
}
}
if msan .Enabled && n > 0 {
msan .Write (unsafe .Pointer (&p [0 ]), uintptr (n ))
}
if asan .Enabled && n > 0 {
asan .Write (unsafe .Pointer (&p [0 ]), uintptr (n ))
}
return
}
func Pwrite (fd int , p []byte , offset int64 ) (n int , err error ) {
if race .Enabled {
race .ReleaseMerge (unsafe .Pointer (&ioSync ))
}
n , err = pwrite (fd , p , offset )
if race .Enabled && n > 0 {
race .ReadRange (unsafe .Pointer (&p [0 ]), n )
}
if msan .Enabled && n > 0 {
msan .Read (unsafe .Pointer (&p [0 ]), uintptr (n ))
}
if asan .Enabled && n > 0 {
asan .Read (unsafe .Pointer (&p [0 ]), uintptr (n ))
}
return
}
var SocketDisableIPv6 bool
type Sockaddr interface {
sockaddr() (ptr unsafe .Pointer , len _Socklen , err error )
}
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 Bind (fd int , sa Sockaddr ) (err error ) {
ptr , n , err := sa .sockaddr ()
if err != nil {
return err
}
return bind (fd , ptr , n )
}
func Connect (fd int , sa Sockaddr ) (err error ) {
ptr , n , err := sa .sockaddr ()
if err != nil {
return err
}
return connect (fd , ptr , n )
}
func Getpeername (fd int ) (sa Sockaddr , err error ) {
var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny
if err = getpeername (fd , &rsa , &len ); err != nil {
return
}
return anyToSockaddr (&rsa )
}
func GetsockoptInt (fd , level , opt int ) (value int , err error ) {
var n int32
vallen := _Socklen (4 )
err = getsockopt (fd , level , opt , unsafe .Pointer (&n ), &vallen )
return int (n ), err
}
func Recvfrom (fd int , p []byte , flags int ) (n int , from Sockaddr , err error ) {
var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny
if n , err = recvfrom (fd , p , flags , &rsa , &len ); err != nil {
return
}
if rsa .Addr .Family != AF_UNSPEC {
from , err = anyToSockaddr (&rsa )
}
return
}
func recvfromInet4(fd int , p []byte , flags int , from *SockaddrInet4 ) (n int , err error ) {
var rsa RawSockaddrAny
var socklen _Socklen = SizeofSockaddrAny
if n , err = recvfrom (fd , p , flags , &rsa , &socklen ); err != nil {
return
}
pp := (*RawSockaddrInet4 )(unsafe .Pointer (&rsa ))
port := (*[2 ]byte )(unsafe .Pointer (&pp .Port ))
from .Port = int (port [0 ])<<8 + int (port [1 ])
from .Addr = pp .Addr
return
}
func recvfromInet6(fd int , p []byte , flags int , from *SockaddrInet6 ) (n int , err error ) {
var rsa RawSockaddrAny
var socklen _Socklen = SizeofSockaddrAny
if n , err = recvfrom (fd , p , flags , &rsa , &socklen ); err != nil {
return
}
pp := (*RawSockaddrInet6 )(unsafe .Pointer (&rsa ))
port := (*[2 ]byte )(unsafe .Pointer (&pp .Port ))
from .Port = int (port [0 ])<<8 + int (port [1 ])
from .ZoneId = pp .Scope_id
from .Addr = pp .Addr
return
}
func recvmsgInet4(fd int , p , oob []byte , flags int , from *SockaddrInet4 ) (n , oobn int , recvflags int , err error ) {
var rsa RawSockaddrAny
n , oobn , recvflags , err = recvmsgRaw (fd , p , oob , flags , &rsa )
if err != nil {
return
}
pp := (*RawSockaddrInet4 )(unsafe .Pointer (&rsa ))
port := (*[2 ]byte )(unsafe .Pointer (&pp .Port ))
from .Port = int (port [0 ])<<8 + int (port [1 ])
from .Addr = pp .Addr
return
}
func recvmsgInet6(fd int , p , oob []byte , flags int , from *SockaddrInet6 ) (n , oobn int , recvflags int , err error ) {
var rsa RawSockaddrAny
n , oobn , recvflags , err = recvmsgRaw (fd , p , oob , flags , &rsa )
if err != nil {
return
}
pp := (*RawSockaddrInet6 )(unsafe .Pointer (&rsa ))
port := (*[2 ]byte )(unsafe .Pointer (&pp .Port ))
from .Port = int (port [0 ])<<8 + int (port [1 ])
from .ZoneId = pp .Scope_id
from .Addr = pp .Addr
return
}
func Recvmsg (fd int , p , oob []byte , flags int ) (n , oobn int , recvflags int , from Sockaddr , err error ) {
var rsa RawSockaddrAny
n , oobn , recvflags , err = recvmsgRaw (fd , p , oob , flags , &rsa )
if rsa .Addr .Family != AF_UNSPEC {
from , err = anyToSockaddr (&rsa )
}
return
}
func Sendmsg (fd int , p , oob []byte , to Sockaddr , flags int ) (err error ) {
_, err = SendmsgN (fd , p , oob , to , flags )
return
}
func SendmsgN (fd int , p , oob []byte , to Sockaddr , flags int ) (n int , err error ) {
var ptr unsafe .Pointer
var salen _Socklen
if to != nil {
ptr , salen , err = to .sockaddr ()
if err != nil {
return 0 , err
}
}
return sendmsgN (fd , p , oob , ptr , salen , flags )
}
func sendmsgNInet4(fd int , p , oob []byte , to *SockaddrInet4 , flags int ) (n int , err error ) {
ptr , salen , err := to .sockaddr ()
if err != nil {
return 0 , err
}
return sendmsgN (fd , p , oob , ptr , salen , flags )
}
func sendmsgNInet6(fd int , p , oob []byte , to *SockaddrInet6 , flags int ) (n int , err error ) {
ptr , salen , err := to .sockaddr ()
if err != nil {
return 0 , err
}
return sendmsgN (fd , p , oob , ptr , salen , flags )
}
func sendtoInet4(fd int , p []byte , flags int , to *SockaddrInet4 ) (err error ) {
ptr , n , err := to .sockaddr ()
if err != nil {
return err
}
return sendto (fd , p , flags , ptr , n )
}
func sendtoInet6(fd int , p []byte , flags int , to *SockaddrInet6 ) (err error ) {
ptr , n , err := to .sockaddr ()
if err != nil {
return err
}
return sendto (fd , p , flags , ptr , n )
}
func Sendto (fd int , p []byte , flags int , to Sockaddr ) (err error ) {
var (
ptr unsafe .Pointer
salen _Socklen
)
if to != nil {
ptr , salen , err = to .sockaddr ()
if err != nil {
return err
}
}
return sendto (fd , p , flags , ptr , salen )
}
func SetsockoptByte (fd , level , opt int , value byte ) (err error ) {
return setsockopt (fd , level , opt , unsafe .Pointer (&value ), 1 )
}
func SetsockoptInt (fd , level , opt int , value int ) (err error ) {
var n = int32 (value )
return setsockopt (fd , level , opt , unsafe .Pointer (&n ), 4 )
}
func SetsockoptInet4Addr (fd , level , opt int , value [4 ]byte ) (err error ) {
return setsockopt (fd , level , opt , unsafe .Pointer (&value [0 ]), 4 )
}
func SetsockoptIPMreq (fd , level , opt int , mreq *IPMreq ) (err error ) {
return setsockopt (fd , level , opt , unsafe .Pointer (mreq ), SizeofIPMreq )
}
func SetsockoptIPv6Mreq (fd , level , opt int , mreq *IPv6Mreq ) (err error ) {
return setsockopt (fd , level , opt , unsafe .Pointer (mreq ), SizeofIPv6Mreq )
}
func SetsockoptICMPv6Filter (fd , level , opt int , filter *ICMPv6Filter ) error {
return setsockopt (fd , level , opt , unsafe .Pointer (filter ), SizeofICMPv6Filter )
}
func SetsockoptLinger (fd , level , opt int , l *Linger ) (err error ) {
return setsockopt (fd , level , opt , unsafe .Pointer (l ), SizeofLinger )
}
func SetsockoptString (fd , level , opt int , s string ) (err error ) {
var p unsafe .Pointer
if len (s ) > 0 {
p = unsafe .Pointer (&[]byte (s )[0 ])
}
return setsockopt (fd , level , opt , p , uintptr (len (s )))
}
func SetsockoptTimeval (fd , level , opt int , tv *Timeval ) (err error ) {
return setsockopt (fd , level , opt , unsafe .Pointer (tv ), unsafe .Sizeof (*tv ))
}
func Socket (domain , typ , proto int ) (fd int , err error ) {
if domain == AF_INET6 && SocketDisableIPv6 {
return -1 , EAFNOSUPPORT
}
fd , err = socket (domain , typ , proto )
return
}
func Socketpair (domain , typ , proto int ) (fd [2 ]int , err error ) {
var fdx [2 ]int32
err = socketpair (domain , typ , proto , &fdx )
if err == nil {
fd [0 ] = int (fdx [0 ])
fd [1 ] = int (fdx [1 ])
}
return
}
func Sendfile (outfd int , infd int , offset *int64 , count int ) (written int , err error ) {
if race .Enabled {
race .ReleaseMerge (unsafe .Pointer (&ioSync ))
}
return sendfile (outfd , infd , offset , count )
}
var ioSync int64
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .