package syscall
import (
"internal/itoa"
"runtime"
"unsafe"
)
func RawSyscall6 (trap , a1 , a2 , a3 , a4 , a5 , a6 uintptr ) (r1 , r2 uintptr , err Errno )
func runtime_entersyscall ()
func runtime_exitsyscall ()
func RawSyscall (trap , a1 , a2 , a3 uintptr ) (r1 , r2 uintptr , err Errno ) {
return RawSyscall6 (trap , a1 , a2 , a3 , 0 , 0 , 0 )
}
func Syscall (trap , a1 , a2 , a3 uintptr ) (r1 , r2 uintptr , err Errno ) {
runtime_entersyscall ()
r1 , r2 , err = RawSyscall6 (trap , a1 , a2 , a3 , 0 , 0 , 0 )
runtime_exitsyscall ()
return
}
func Syscall6 (trap , a1 , a2 , a3 , a4 , a5 , a6 uintptr ) (r1 , r2 uintptr , err Errno ) {
runtime_entersyscall ()
r1 , r2 , err = RawSyscall6 (trap , a1 , a2 , a3 , a4 , a5 , a6 )
runtime_exitsyscall ()
return
}
func rawSyscallNoError (trap , a1 , a2 , a3 uintptr ) (r1 , r2 uintptr )
func rawVforkSyscall (trap , a1 , a2 uintptr ) (r1 uintptr , err Errno )
func Access (path string , mode uint32 ) (err error ) {
return Faccessat (_AT_FDCWD , path , mode , 0 )
}
func Chmod (path string , mode uint32 ) (err error ) {
return Fchmodat (_AT_FDCWD , path , mode , 0 )
}
func Chown (path string , uid int , gid int ) (err error ) {
return Fchownat (_AT_FDCWD , path , uid , gid , 0 )
}
func Creat (path string , mode uint32 ) (fd int , err error ) {
return Open (path , O_CREAT |O_WRONLY |O_TRUNC , mode )
}
func EpollCreate (size int ) (fd int , err error ) {
if size <= 0 {
return -1 , EINVAL
}
return EpollCreate1 (0 )
}
func isGroupMember (gid int ) bool {
groups , err := Getgroups ()
if err != nil {
return false
}
for _ , g := range groups {
if g == gid {
return true
}
}
return false
}
func isCapDacOverrideSet () bool {
const _CAP_DAC_OVERRIDE = 1
var c caps
c .hdr .version = _LINUX_CAPABILITY_VERSION_3
_ , _ , err := RawSyscall (SYS_CAPGET , uintptr (unsafe .Pointer (&c .hdr )), uintptr (unsafe .Pointer (&c .data [0 ])), 0 )
return err == 0 && c .data [0 ].effective &capToMask (_CAP_DAC_OVERRIDE ) != 0
}
func Faccessat (dirfd int , path string , mode uint32 , flags int ) (err error ) {
if flags == 0 {
return faccessat (dirfd , path , mode )
}
if runtime .GOOS != "android" {
if err := faccessat2 (dirfd , path , mode , flags ); err != ENOSYS && err != EPERM {
return err
}
}
if flags & ^(_AT_SYMLINK_NOFOLLOW |_AT_EACCESS ) != 0 {
return EINVAL
}
var st Stat_t
if err := fstatat (dirfd , path , &st , flags &_AT_SYMLINK_NOFOLLOW ); err != nil {
return err
}
mode &= 7
if mode == 0 {
return nil
}
var uid int
if flags &_AT_EACCESS != 0 {
uid = Geteuid ()
if uid != 0 && isCapDacOverrideSet () {
uid = 0
}
} else {
uid = Getuid ()
}
if uid == 0 {
if mode &1 == 0 {
return nil
}
if st .Mode &0111 != 0 {
return nil
}
return EACCES
}
var fmode uint32
if uint32 (uid ) == st .Uid {
fmode = (st .Mode >> 6 ) & 7
} else {
var gid int
if flags &_AT_EACCESS != 0 {
gid = Getegid ()
} else {
gid = Getgid ()
}
if uint32 (gid ) == st .Gid || isGroupMember (int (st .Gid )) {
fmode = (st .Mode >> 3 ) & 7
} else {
fmode = st .Mode & 7
}
}
if fmode &mode == mode {
return nil
}
return EACCES
}
func Fchmodat (dirfd int , path string , mode uint32 , flags int ) (err error ) {
if flags &^_AT_SYMLINK_NOFOLLOW != 0 {
return EINVAL
} else if flags &_AT_SYMLINK_NOFOLLOW != 0 {
return EOPNOTSUPP
}
return fchmodat (dirfd , path , mode )
}
func Link (oldpath string , newpath string ) (err error ) {
return linkat (_AT_FDCWD , oldpath , _AT_FDCWD , newpath , 0 )
}
func Mkdir (path string , mode uint32 ) (err error ) {
return Mkdirat (_AT_FDCWD , path , mode )
}
func Mknod (path string , mode uint32 , dev int ) (err error ) {
return Mknodat (_AT_FDCWD , path , mode , dev )
}
func Open (path string , mode int , perm uint32 ) (fd int , err error ) {
return openat (_AT_FDCWD , path , mode |O_LARGEFILE , perm )
}
func Openat (dirfd int , path string , flags int , mode uint32 ) (fd int , err error ) {
return openat (dirfd , path , flags |O_LARGEFILE , mode )
}
func Pipe (p []int ) error {
return Pipe2 (p , 0 )
}
func Pipe2 (p []int , flags int ) error {
if len (p ) != 2 {
return EINVAL
}
var pp [2 ]_C_int
err := pipe2 (&pp , flags )
if err == nil {
p [0 ] = int (pp [0 ])
p [1 ] = int (pp [1 ])
}
return err
}
func Readlink (path string , buf []byte ) (n int , err error ) {
return readlinkat (_AT_FDCWD , path , buf )
}
func Rename (oldpath string , newpath string ) (err error ) {
return Renameat (_AT_FDCWD , oldpath , _AT_FDCWD , newpath )
}
func Rmdir (path string ) error {
return unlinkat (_AT_FDCWD , path , _AT_REMOVEDIR )
}
func Symlink (oldpath string , newpath string ) (err error ) {
return symlinkat (oldpath , _AT_FDCWD , newpath )
}
func Unlink (path string ) error {
return unlinkat (_AT_FDCWD , path , 0 )
}
func Unlinkat (dirfd int , path string ) error {
return unlinkat (dirfd , path , 0 )
}
func Utimes (path string , tv []Timeval ) (err error ) {
if len (tv ) != 2 {
return EINVAL
}
return utimes (path , (*[2 ]Timeval )(unsafe .Pointer (&tv [0 ])))
}
func UtimesNano (path string , ts []Timespec ) (err error ) {
if len (ts ) != 2 {
return EINVAL
}
return utimensat (_AT_FDCWD , path , (*[2 ]Timespec )(unsafe .Pointer (&ts [0 ])), 0 )
}
func Futimesat (dirfd int , path string , tv []Timeval ) (err error ) {
if len (tv ) != 2 {
return EINVAL
}
return futimesat (dirfd , path , (*[2 ]Timeval )(unsafe .Pointer (&tv [0 ])))
}
func Futimes (fd int , tv []Timeval ) (err error ) {
return Utimes ("/proc/self/fd/" +itoa .Itoa (fd ), tv )
}
const ImplementsGetwd = true
func Getwd () (wd string , err error ) {
var buf [PathMax ]byte
n , err := Getcwd (buf [0 :])
if err != nil {
return "" , err
}
if n < 1 || n > len (buf ) || buf [n -1 ] != 0 {
return "" , EINVAL
}
if buf [0 ] != '/' {
return "" , ENOENT
}
return string (buf [0 : n -1 ]), nil
}
func Getgroups () (gids []int , err error ) {
n , err := getgroups (0 , nil )
if err != nil {
return nil , err
}
if n == 0 {
return nil , nil
}
if n < 0 || n > 1 <<20 {
return nil , EINVAL
}
a := make ([]_Gid_t , n )
n , err = getgroups (n , &a [0 ])
if err != nil {
return nil , err
}
gids = make ([]int , n )
for i , v := range a [0 :n ] {
gids [i ] = int (v )
}
return
}
var cgo_libc_setgroups unsafe .Pointer
func Setgroups (gids []int ) (err error ) {
n := uintptr (len (gids ))
if n == 0 {
if cgo_libc_setgroups == nil {
if _ , _ , e1 := AllThreadsSyscall (_SYS_setgroups , 0 , 0 , 0 ); e1 != 0 {
err = errnoErr (e1 )
}
return
}
if ret := cgocaller (cgo_libc_setgroups , 0 , 0 ); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
a := make ([]_Gid_t , len (gids ))
for i , v := range gids {
a [i ] = _Gid_t (v )
}
if cgo_libc_setgroups == nil {
if _ , _ , e1 := AllThreadsSyscall (_SYS_setgroups , n , uintptr (unsafe .Pointer (&a [0 ])), 0 ); e1 != 0 {
err = errnoErr (e1 )
}
return
}
if ret := cgocaller (cgo_libc_setgroups , n , uintptr (unsafe .Pointer (&a [0 ]))); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
type WaitStatus uint32
const (
mask = 0x7F
core = 0x80
exited = 0x00
stopped = 0x7F
shift = 8
)
func (w WaitStatus ) Exited () bool { return w &mask == exited }
func (w WaitStatus ) Signaled () bool { return w &mask != stopped && w &mask != exited }
func (w WaitStatus ) Stopped () bool { return w &0xFF == stopped }
func (w WaitStatus ) Continued () bool { return w == 0xFFFF }
func (w WaitStatus ) CoreDump () bool { return w .Signaled () && w &core != 0 }
func (w WaitStatus ) ExitStatus () int {
if !w .Exited () {
return -1
}
return int (w >>shift ) & 0xFF
}
func (w WaitStatus ) Signal () Signal {
if !w .Signaled () {
return -1
}
return Signal (w & mask )
}
func (w WaitStatus ) StopSignal () Signal {
if !w .Stopped () {
return -1
}
return Signal (w >>shift ) & 0xFF
}
func (w WaitStatus ) TrapCause () int {
if w .StopSignal () != SIGTRAP {
return -1
}
return int (w >>shift ) >> 8
}
func Wait4 (pid int , wstatus *WaitStatus , options int , rusage *Rusage ) (wpid int , err error ) {
var status _C_int
wpid , err = wait4 (pid , &status , options , rusage )
if wstatus != nil {
*wstatus = WaitStatus (status )
}
return
}
func Mkfifo (path string , mode uint32 ) (err error ) {
return Mknod (path , mode |S_IFIFO , 0 )
}
func (sa *SockaddrInet4 ) sockaddr () (unsafe .Pointer , _Socklen , error ) {
if sa .Port < 0 || sa .Port > 0xFFFF {
return nil , 0 , EINVAL
}
sa .raw .Family = AF_INET
p := (*[2 ]byte )(unsafe .Pointer (&sa .raw .Port ))
p [0 ] = byte (sa .Port >> 8 )
p [1 ] = byte (sa .Port )
sa .raw .Addr = sa .Addr
return unsafe .Pointer (&sa .raw ), SizeofSockaddrInet4 , nil
}
func (sa *SockaddrInet6 ) sockaddr () (unsafe .Pointer , _Socklen , error ) {
if sa .Port < 0 || sa .Port > 0xFFFF {
return nil , 0 , EINVAL
}
sa .raw .Family = AF_INET6
p := (*[2 ]byte )(unsafe .Pointer (&sa .raw .Port ))
p [0 ] = byte (sa .Port >> 8 )
p [1 ] = byte (sa .Port )
sa .raw .Scope_id = sa .ZoneId
sa .raw .Addr = sa .Addr
return unsafe .Pointer (&sa .raw ), SizeofSockaddrInet6 , nil
}
func (sa *SockaddrUnix ) sockaddr () (unsafe .Pointer , _Socklen , error ) {
name := sa .Name
n := len (name )
if n > len (sa .raw .Path ) {
return nil , 0 , EINVAL
}
if n == len (sa .raw .Path ) && name [0 ] != '@' {
return nil , 0 , EINVAL
}
sa .raw .Family = AF_UNIX
for i := 0 ; i < n ; i ++ {
sa .raw .Path [i ] = int8 (name [i ])
}
sl := _Socklen (2 )
if n > 0 {
sl += _Socklen (n ) + 1
}
if sa .raw .Path [0 ] == '@' {
sa .raw .Path [0 ] = 0
sl --
}
return unsafe .Pointer (&sa .raw ), sl , nil
}
type SockaddrLinklayer struct {
Protocol uint16
Ifindex int
Hatype uint16
Pkttype uint8
Halen uint8
Addr [8 ]byte
raw RawSockaddrLinklayer
}
func (sa *SockaddrLinklayer ) sockaddr () (unsafe .Pointer , _Socklen , error ) {
if sa .Ifindex < 0 || sa .Ifindex > 0x7fffffff {
return nil , 0 , EINVAL
}
sa .raw .Family = AF_PACKET
sa .raw .Protocol = sa .Protocol
sa .raw .Ifindex = int32 (sa .Ifindex )
sa .raw .Hatype = sa .Hatype
sa .raw .Pkttype = sa .Pkttype
sa .raw .Halen = sa .Halen
sa .raw .Addr = sa .Addr
return unsafe .Pointer (&sa .raw ), SizeofSockaddrLinklayer , nil
}
type SockaddrNetlink struct {
Family uint16
Pad uint16
Pid uint32
Groups uint32
raw RawSockaddrNetlink
}
func (sa *SockaddrNetlink ) sockaddr () (unsafe .Pointer , _Socklen , error ) {
sa .raw .Family = AF_NETLINK
sa .raw .Pad = sa .Pad
sa .raw .Pid = sa .Pid
sa .raw .Groups = sa .Groups
return unsafe .Pointer (&sa .raw ), SizeofSockaddrNetlink , nil
}
func anyToSockaddr (rsa *RawSockaddrAny ) (Sockaddr , error ) {
switch rsa .Addr .Family {
case AF_NETLINK :
pp := (*RawSockaddrNetlink )(unsafe .Pointer (rsa ))
sa := new (SockaddrNetlink )
sa .Family = pp .Family
sa .Pad = pp .Pad
sa .Pid = pp .Pid
sa .Groups = pp .Groups
return sa , nil
case AF_PACKET :
pp := (*RawSockaddrLinklayer )(unsafe .Pointer (rsa ))
sa := new (SockaddrLinklayer )
sa .Protocol = pp .Protocol
sa .Ifindex = int (pp .Ifindex )
sa .Hatype = pp .Hatype
sa .Pkttype = pp .Pkttype
sa .Halen = pp .Halen
sa .Addr = pp .Addr
return sa , nil
case AF_UNIX :
pp := (*RawSockaddrUnix )(unsafe .Pointer (rsa ))
sa := new (SockaddrUnix )
if pp .Path [0 ] == 0 {
pp .Path [0 ] = '@'
}
n := 0
for n < len (pp .Path ) && pp .Path [n ] != 0 {
n ++
}
sa .Name = string (unsafe .Slice ((*byte )(unsafe .Pointer (&pp .Path [0 ])), n ))
return sa , nil
case AF_INET :
pp := (*RawSockaddrInet4 )(unsafe .Pointer (rsa ))
sa := new (SockaddrInet4 )
p := (*[2 ]byte )(unsafe .Pointer (&pp .Port ))
sa .Port = int (p [0 ])<<8 + int (p [1 ])
sa .Addr = pp .Addr
return sa , nil
case AF_INET6 :
pp := (*RawSockaddrInet6 )(unsafe .Pointer (rsa ))
sa := new (SockaddrInet6 )
p := (*[2 ]byte )(unsafe .Pointer (&pp .Port ))
sa .Port = int (p [0 ])<<8 + int (p [1 ])
sa .ZoneId = pp .Scope_id
sa .Addr = pp .Addr
return sa , nil
}
return nil , EAFNOSUPPORT
}
func Accept4 (fd int , flags int ) (nfd int , sa Sockaddr , err error ) {
var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny
nfd , err = accept4 (fd , &rsa , &len , flags )
if err != nil {
return
}
if len > SizeofSockaddrAny {
panic ("RawSockaddrAny too small" )
}
sa , err = anyToSockaddr (&rsa )
if err != nil {
Close (nfd )
nfd = 0
}
return
}
func Getsockname (fd int ) (sa Sockaddr , err error ) {
var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny
if err = getsockname (fd , &rsa , &len ); err != nil {
return
}
return anyToSockaddr (&rsa )
}
func GetsockoptInet4Addr (fd , level , opt int ) (value [4 ]byte , err error ) {
vallen := _Socklen (4 )
err = getsockopt (fd , level , opt , unsafe .Pointer (&value [0 ]), &vallen )
return value , err
}
func GetsockoptIPMreq (fd , level , opt int ) (*IPMreq , error ) {
var value IPMreq
vallen := _Socklen (SizeofIPMreq )
err := getsockopt (fd , level , opt , unsafe .Pointer (&value ), &vallen )
return &value , err
}
func GetsockoptIPMreqn (fd , level , opt int ) (*IPMreqn , error ) {
var value IPMreqn
vallen := _Socklen (SizeofIPMreqn )
err := getsockopt (fd , level , opt , unsafe .Pointer (&value ), &vallen )
return &value , err
}
func GetsockoptIPv6Mreq (fd , level , opt int ) (*IPv6Mreq , error ) {
var value IPv6Mreq
vallen := _Socklen (SizeofIPv6Mreq )
err := getsockopt (fd , level , opt , unsafe .Pointer (&value ), &vallen )
return &value , err
}
func GetsockoptIPv6MTUInfo (fd , level , opt int ) (*IPv6MTUInfo , error ) {
var value IPv6MTUInfo
vallen := _Socklen (SizeofIPv6MTUInfo )
err := getsockopt (fd , level , opt , unsafe .Pointer (&value ), &vallen )
return &value , err
}
func GetsockoptICMPv6Filter (fd , level , opt int ) (*ICMPv6Filter , error ) {
var value ICMPv6Filter
vallen := _Socklen (SizeofICMPv6Filter )
err := getsockopt (fd , level , opt , unsafe .Pointer (&value ), &vallen )
return &value , err
}
func GetsockoptUcred (fd , level , opt int ) (*Ucred , error ) {
var value Ucred
vallen := _Socklen (SizeofUcred )
err := getsockopt (fd , level , opt , unsafe .Pointer (&value ), &vallen )
return &value , err
}
func SetsockoptIPMreqn (fd , level , opt int , mreq *IPMreqn ) (err error ) {
return setsockopt (fd , level , opt , unsafe .Pointer (mreq ), unsafe .Sizeof (*mreq ))
}
func recvmsgRaw (fd int , p , oob []byte , flags int , rsa *RawSockaddrAny ) (n , oobn int , recvflags int , err error ) {
var msg Msghdr
msg .Name = (*byte )(unsafe .Pointer (rsa ))
msg .Namelen = uint32 (SizeofSockaddrAny )
var iov Iovec
if len (p ) > 0 {
iov .Base = &p [0 ]
iov .SetLen (len (p ))
}
var dummy byte
if len (oob ) > 0 {
if len (p ) == 0 {
var sockType int
sockType , err = GetsockoptInt (fd , SOL_SOCKET , SO_TYPE )
if err != nil {
return
}
if sockType != SOCK_DGRAM {
iov .Base = &dummy
iov .SetLen (1 )
}
}
msg .Control = &oob [0 ]
msg .SetControllen (len (oob ))
}
msg .Iov = &iov
msg .Iovlen = 1
if n , err = recvmsg (fd , &msg , flags ); err != nil {
return
}
oobn = int (msg .Controllen )
recvflags = int (msg .Flags )
return
}
func sendmsgN (fd int , p , oob []byte , ptr unsafe .Pointer , salen _Socklen , flags int ) (n int , err error ) {
var msg Msghdr
msg .Name = (*byte )(ptr )
msg .Namelen = uint32 (salen )
var iov Iovec
if len (p ) > 0 {
iov .Base = &p [0 ]
iov .SetLen (len (p ))
}
var dummy byte
if len (oob ) > 0 {
if len (p ) == 0 {
var sockType int
sockType , err = GetsockoptInt (fd , SOL_SOCKET , SO_TYPE )
if err != nil {
return 0 , err
}
if sockType != SOCK_DGRAM {
iov .Base = &dummy
iov .SetLen (1 )
}
}
msg .Control = &oob [0 ]
msg .SetControllen (len (oob ))
}
msg .Iov = &iov
msg .Iovlen = 1
if n , err = sendmsg (fd , &msg , flags ); err != nil {
return 0 , err
}
if len (oob ) > 0 && len (p ) == 0 {
n = 0
}
return n , nil
}
func BindToDevice (fd int , device string ) (err error ) {
return SetsockoptString (fd , SOL_SOCKET , SO_BINDTODEVICE , device )
}
func ptracePeek (req int , pid int , addr uintptr , out []byte ) (count int , err error ) {
var buf [sizeofPtr ]byte
n := 0
if addr %sizeofPtr != 0 {
err = ptracePtr (req , pid , addr -addr %sizeofPtr , unsafe .Pointer (&buf [0 ]))
if err != nil {
return 0 , err
}
n += copy (out , buf [addr %sizeofPtr :])
out = out [n :]
}
for len (out ) > 0 {
err = ptracePtr (req , pid , addr +uintptr (n ), unsafe .Pointer (&buf [0 ]))
if err != nil {
return n , err
}
copied := copy (out , buf [0 :])
n += copied
out = out [copied :]
}
return n , nil
}
func PtracePeekText (pid int , addr uintptr , out []byte ) (count int , err error ) {
return ptracePeek (PTRACE_PEEKTEXT , pid , addr , out )
}
func PtracePeekData (pid int , addr uintptr , out []byte ) (count int , err error ) {
return ptracePeek (PTRACE_PEEKDATA , pid , addr , out )
}
func ptracePoke (pokeReq int , peekReq int , pid int , addr uintptr , data []byte ) (count int , err error ) {
n := 0
if addr %sizeofPtr != 0 {
var buf [sizeofPtr ]byte
err = ptracePtr (peekReq , pid , addr -addr %sizeofPtr , unsafe .Pointer (&buf [0 ]))
if err != nil {
return 0 , err
}
n += copy (buf [addr %sizeofPtr :], data )
word := *((*uintptr )(unsafe .Pointer (&buf [0 ])))
err = ptrace (pokeReq , pid , addr -addr %sizeofPtr , word )
if err != nil {
return 0 , err
}
data = data [n :]
}
for len (data ) > sizeofPtr {
word := *((*uintptr )(unsafe .Pointer (&data [0 ])))
err = ptrace (pokeReq , pid , addr +uintptr (n ), word )
if err != nil {
return n , err
}
n += sizeofPtr
data = data [sizeofPtr :]
}
if len (data ) > 0 {
var buf [sizeofPtr ]byte
err = ptracePtr (peekReq , pid , addr +uintptr (n ), unsafe .Pointer (&buf [0 ]))
if err != nil {
return n , err
}
copy (buf [0 :], data )
word := *((*uintptr )(unsafe .Pointer (&buf [0 ])))
err = ptrace (pokeReq , pid , addr +uintptr (n ), word )
if err != nil {
return n , err
}
n += len (data )
}
return n , nil
}
func PtracePokeText (pid int , addr uintptr , data []byte ) (count int , err error ) {
return ptracePoke (PTRACE_POKETEXT , PTRACE_PEEKTEXT , pid , addr , data )
}
func PtracePokeData (pid int , addr uintptr , data []byte ) (count int , err error ) {
return ptracePoke (PTRACE_POKEDATA , PTRACE_PEEKDATA , pid , addr , data )
}
const (
_NT_PRSTATUS = 1
)
func PtraceGetRegs (pid int , regsout *PtraceRegs ) (err error ) {
var iov Iovec
iov .Base = (*byte )(unsafe .Pointer (regsout ))
iov .SetLen (int (unsafe .Sizeof (*regsout )))
return ptracePtr (PTRACE_GETREGSET , pid , uintptr (_NT_PRSTATUS ), unsafe .Pointer (&iov ))
}
func PtraceSetRegs (pid int , regs *PtraceRegs ) (err error ) {
var iov Iovec
iov .Base = (*byte )(unsafe .Pointer (regs ))
iov .SetLen (int (unsafe .Sizeof (*regs )))
return ptracePtr (PTRACE_SETREGSET , pid , uintptr (_NT_PRSTATUS ), unsafe .Pointer (&iov ))
}
func PtraceSetOptions (pid int , options int ) (err error ) {
return ptrace (PTRACE_SETOPTIONS , pid , 0 , uintptr (options ))
}
func PtraceGetEventMsg (pid int ) (msg uint , err error ) {
var data _C_long
err = ptracePtr (PTRACE_GETEVENTMSG , pid , 0 , unsafe .Pointer (&data ))
msg = uint (data )
return
}
func PtraceCont (pid int , signal int ) (err error ) {
return ptrace (PTRACE_CONT , pid , 0 , uintptr (signal ))
}
func PtraceSyscall (pid int , signal int ) (err error ) {
return ptrace (PTRACE_SYSCALL , pid , 0 , uintptr (signal ))
}
func PtraceSingleStep (pid int ) (err error ) { return ptrace (PTRACE_SINGLESTEP , pid , 0 , 0 ) }
func PtraceAttach (pid int ) (err error ) { return ptrace (PTRACE_ATTACH , pid , 0 , 0 ) }
func PtraceDetach (pid int ) (err error ) { return ptrace (PTRACE_DETACH , pid , 0 , 0 ) }
func Reboot (cmd int ) (err error ) {
return reboot (LINUX_REBOOT_MAGIC1 , LINUX_REBOOT_MAGIC2 , cmd , "" )
}
func ReadDirent (fd int , buf []byte ) (n int , err error ) {
return Getdents (fd , buf )
}
func direntIno (buf []byte ) (uint64 , bool ) {
return readInt (buf , unsafe .Offsetof (Dirent {}.Ino ), unsafe .Sizeof (Dirent {}.Ino ))
}
func direntReclen (buf []byte ) (uint64 , bool ) {
return readInt (buf , unsafe .Offsetof (Dirent {}.Reclen ), unsafe .Sizeof (Dirent {}.Reclen ))
}
func direntNamlen (buf []byte ) (uint64 , bool ) {
reclen , ok := direntReclen (buf )
if !ok {
return 0 , false
}
return reclen - uint64 (unsafe .Offsetof (Dirent {}.Name )), true
}
func Mount (source string , target string , fstype string , flags uintptr , data string ) (err error ) {
if data == "" {
return mount (source , target , fstype , flags , nil )
}
datap , err := BytePtrFromString (data )
if err != nil {
return err
}
return mount (source , target , fstype , flags , datap )
}
func Getpgrp () (pid int ) {
pid , _ = Getpgid (0 )
return
}
func runtime_doAllThreadsSyscall (trap , a1 , a2 , a3 , a4 , a5 , a6 uintptr ) (r1 , r2 , err uintptr )
func AllThreadsSyscall (trap , a1 , a2 , a3 uintptr ) (r1 , r2 uintptr , err Errno ) {
if cgo_libc_setegid != nil {
return minus1 , minus1 , ENOTSUP
}
r1 , r2 , errno := runtime_doAllThreadsSyscall (trap , a1 , a2 , a3 , 0 , 0 , 0 )
return r1 , r2 , Errno (errno )
}
func AllThreadsSyscall6 (trap , a1 , a2 , a3 , a4 , a5 , a6 uintptr ) (r1 , r2 uintptr , err Errno ) {
if cgo_libc_setegid != nil {
return minus1 , minus1 , ENOTSUP
}
r1 , r2 , errno := runtime_doAllThreadsSyscall (trap , a1 , a2 , a3 , a4 , a5 , a6 )
return r1 , r2 , Errno (errno )
}
func cgocaller (unsafe .Pointer , ...uintptr ) uintptr
var cgo_libc_setegid unsafe .Pointer
const minus1 = ^uintptr (0 )
func Setegid (egid int ) (err error ) {
if cgo_libc_setegid == nil {
if _ , _ , e1 := AllThreadsSyscall (SYS_SETRESGID , minus1 , uintptr (egid ), minus1 ); e1 != 0 {
err = errnoErr (e1 )
}
} else if ret := cgocaller (cgo_libc_setegid , uintptr (egid )); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
var cgo_libc_seteuid unsafe .Pointer
func Seteuid (euid int ) (err error ) {
if cgo_libc_seteuid == nil {
if _ , _ , e1 := AllThreadsSyscall (SYS_SETRESUID , minus1 , uintptr (euid ), minus1 ); e1 != 0 {
err = errnoErr (e1 )
}
} else if ret := cgocaller (cgo_libc_seteuid , uintptr (euid )); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
var cgo_libc_setgid unsafe .Pointer
func Setgid (gid int ) (err error ) {
if cgo_libc_setgid == nil {
if _ , _ , e1 := AllThreadsSyscall (sys_SETGID , uintptr (gid ), 0 , 0 ); e1 != 0 {
err = errnoErr (e1 )
}
} else if ret := cgocaller (cgo_libc_setgid , uintptr (gid )); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
var cgo_libc_setregid unsafe .Pointer
func Setregid (rgid , egid int ) (err error ) {
if cgo_libc_setregid == nil {
if _ , _ , e1 := AllThreadsSyscall (sys_SETREGID , uintptr (rgid ), uintptr (egid ), 0 ); e1 != 0 {
err = errnoErr (e1 )
}
} else if ret := cgocaller (cgo_libc_setregid , uintptr (rgid ), uintptr (egid )); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
var cgo_libc_setresgid unsafe .Pointer
func Setresgid (rgid , egid , sgid int ) (err error ) {
if cgo_libc_setresgid == nil {
if _ , _ , e1 := AllThreadsSyscall (sys_SETRESGID , uintptr (rgid ), uintptr (egid ), uintptr (sgid )); e1 != 0 {
err = errnoErr (e1 )
}
} else if ret := cgocaller (cgo_libc_setresgid , uintptr (rgid ), uintptr (egid ), uintptr (sgid )); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
var cgo_libc_setresuid unsafe .Pointer
func Setresuid (ruid , euid , suid int ) (err error ) {
if cgo_libc_setresuid == nil {
if _ , _ , e1 := AllThreadsSyscall (sys_SETRESUID , uintptr (ruid ), uintptr (euid ), uintptr (suid )); e1 != 0 {
err = errnoErr (e1 )
}
} else if ret := cgocaller (cgo_libc_setresuid , uintptr (ruid ), uintptr (euid ), uintptr (suid )); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
var cgo_libc_setreuid unsafe .Pointer
func Setreuid (ruid , euid int ) (err error ) {
if cgo_libc_setreuid == nil {
if _ , _ , e1 := AllThreadsSyscall (sys_SETREUID , uintptr (ruid ), uintptr (euid ), 0 ); e1 != 0 {
err = errnoErr (e1 )
}
} else if ret := cgocaller (cgo_libc_setreuid , uintptr (ruid ), uintptr (euid )); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
var cgo_libc_setuid unsafe .Pointer
func Setuid (uid int ) (err error ) {
if cgo_libc_setuid == nil {
if _ , _ , e1 := AllThreadsSyscall (sys_SETUID , uintptr (uid ), 0 , 0 ); e1 != 0 {
err = errnoErr (e1 )
}
} else if ret := cgocaller (cgo_libc_setuid , uintptr (uid )); ret != 0 {
err = errnoErr (Errno (ret ))
}
return
}
var mapper = &mmapper {
active : make (map [*byte ][]byte ),
mmap : mmap ,
munmap : munmap ,
}
func Mmap (fd int , offset int64 , length int , prot int , flags int ) (data []byte , err error ) {
return mapper .Mmap (fd , offset , length , prot , flags )
}
func Munmap (b []byte ) (err error ) {
return mapper .Munmap (b )
}
func prlimit (pid int , resource int , newlimit *Rlimit , old *Rlimit ) (err error ) {
err = prlimit1 (pid , resource , newlimit , old )
if err == nil && newlimit != nil && resource == RLIMIT_NOFILE {
origRlimitNofile .Store (Rlimit {0 , 0 })
}
return err
}
The pages are generated with Golds v0.6.7 . (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 @Go100and1 (reachable from the left QR code) to get the latest news of Golds .