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