1// Copyright 2016 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 5package syscall 6 7import "unsafe" 8 9const ( 10 _SYS_setgroups = SYS_SETGROUPS 11 _SYS_clone3 = 435 12 _SYS_faccessat2 = 439 13 _SYS_fchmodat2 = 452 14) 15 16//sys Dup2(oldfd int, newfd int) (err error) 17//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) 18//sys Fchown(fd int, uid int, gid int) (err error) 19//sys Fstat(fd int, stat *Stat_t) (err error) 20//sys fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT 21//sys Fstatfs(fd int, buf *Statfs_t) (err error) 22//sys Ftruncate(fd int, length int64) (err error) 23//sysnb Getegid() (egid int) 24//sysnb Geteuid() (euid int) 25//sysnb Getgid() (gid int) 26//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT 27//sysnb Getuid() (uid int) 28//sysnb InotifyInit() (fd int, err error) 29//sys Lchown(path string, uid int, gid int) (err error) 30//sys Lstat(path string, stat *Stat_t) (err error) 31//sys Pause() (err error) 32//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 33//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 34//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) 35//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK 36//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) 37//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) 38//sys Setfsgid(gid int) (err error) 39//sys Setfsuid(uid int) (err error) 40//sysnb setrlimit(resource int, rlim *Rlimit) (err error) = SYS_SETRLIMIT 41//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) 42//sys Stat(path string, stat *Stat_t) (err error) 43//sys Statfs(path string, buf *Statfs_t) (err error) 44//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE 45//sys Truncate(path string, length int64) (err error) 46//sys Ustat(dev int, ubuf *Ustat_t) (err error) 47//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) 48 49//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) 50//sysnb Gettimeofday(tv *Timeval) (err error) 51 52func Time(t *Time_t) (tt Time_t, err error) { 53 var tv Timeval 54 err = Gettimeofday(&tv) 55 if err != nil { 56 return 0, err 57 } 58 if t != nil { 59 *t = Time_t(tv.Sec) 60 } 61 return Time_t(tv.Sec), nil 62} 63 64//sys Utime(path string, buf *Utimbuf) (err error) 65//sys utimes(path string, times *[2]Timeval) (err error) 66 67func setTimespec(sec, nsec int64) Timespec { 68 return Timespec{Sec: sec, Nsec: nsec} 69} 70 71func setTimeval(sec, usec int64) Timeval { 72 return Timeval{Sec: sec, Usec: usec} 73} 74 75// Linux on s390x uses the old mmap interface, which requires arguments to be passed in a struct. 76// mmap2 also requires arguments to be passed in a struct; it is currently not exposed in <asm/unistd.h>. 77func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { 78 mmap_args := [6]uintptr{addr, length, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)} 79 r0, _, e1 := Syscall(SYS_MMAP, uintptr(unsafe.Pointer(&mmap_args[0])), 0, 0) 80 xaddr = uintptr(r0) 81 if e1 != 0 { 82 err = errnoErr(e1) 83 } 84 return 85} 86 87// On s390x Linux, all the socket calls go through an extra indirection. 88// The arguments to the underlying system call are the number below 89// and a pointer to an array of uintptr. We hide the pointer in the 90// socketcall assembly to avoid allocation on every system call. 91 92const ( 93 // see linux/net.h 94 _SOCKET = 1 95 _BIND = 2 96 _CONNECT = 3 97 _LISTEN = 4 98 _ACCEPT = 5 99 _GETSOCKNAME = 6 100 _GETPEERNAME = 7 101 _SOCKETPAIR = 8 102 _SEND = 9 103 _RECV = 10 104 _SENDTO = 11 105 _RECVFROM = 12 106 _SHUTDOWN = 13 107 _SETSOCKOPT = 14 108 _GETSOCKOPT = 15 109 _SENDMSG = 16 110 _RECVMSG = 17 111 _ACCEPT4 = 18 112 _RECVMMSG = 19 113 _SENDMMSG = 20 114) 115 116func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno) 117func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno) 118 119func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { 120 fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) 121 if e != 0 { 122 err = e 123 } 124 return 125} 126 127func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { 128 _, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) 129 if e != 0 { 130 err = e 131 } 132 return 133} 134 135func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { 136 _, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) 137 if e != 0 { 138 err = e 139 } 140 return 141} 142 143func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) { 144 _, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0) 145 if e != 0 { 146 err = e 147 } 148 return 149} 150 151func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { 152 _, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) 153 if e != 0 { 154 err = e 155 } 156 return 157} 158 159func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { 160 _, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) 161 if e != 0 { 162 err = e 163 } 164 return 165} 166 167func socket(domain int, typ int, proto int) (fd int, err error) { 168 fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0) 169 if e != 0 { 170 err = e 171 } 172 return 173} 174 175func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { 176 _, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) 177 if e != 0 { 178 err = e 179 } 180 return 181} 182 183func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { 184 _, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0) 185 if e != 0 { 186 err = e 187 } 188 return 189} 190 191func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { 192 var base uintptr 193 if len(p) > 0 { 194 base = uintptr(unsafe.Pointer(&p[0])) 195 } 196 n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) 197 if e != 0 { 198 err = e 199 } 200 return 201} 202 203func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { 204 var base uintptr 205 if len(p) > 0 { 206 base = uintptr(unsafe.Pointer(&p[0])) 207 } 208 _, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen)) 209 if e != 0 { 210 err = e 211 } 212 return 213} 214 215func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { 216 n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) 217 if e != 0 { 218 err = e 219 } 220 return 221} 222 223func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { 224 n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) 225 if e != 0 { 226 err = e 227 } 228 return 229} 230 231func Listen(s int, n int) (err error) { 232 _, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0) 233 if e != 0 { 234 err = e 235 } 236 return 237} 238 239func Shutdown(s, how int) (err error) { 240 _, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0) 241 if e != 0 { 242 err = e 243 } 244 return 245} 246 247//go:nosplit 248func rawSetrlimit(resource int, rlim *Rlimit) Errno { 249 _, _, errno := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) 250 return errno 251} 252 253func (r *PtraceRegs) PC() uint64 { return r.Psw.Addr } 254 255func (r *PtraceRegs) SetPC(pc uint64) { r.Psw.Addr = pc } 256 257func (iov *Iovec) SetLen(length int) { 258 iov.Len = uint64(length) 259} 260 261func (msghdr *Msghdr) SetControllen(length int) { 262 msghdr.Controllen = uint64(length) 263} 264 265func (cmsg *Cmsghdr) SetLen(length int) { 266 cmsg.Len = uint64(length) 267} 268