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