1// Copyright 2009 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
5// Solaris system calls.
6// This file is compiled as ordinary Go code,
7// but it is also input to mksyscall,
8// which parses the //sys lines and generates system call stubs.
9// Note that sometimes we use a lowercase //sys name and wrap
10// it in our own nicer implementation, either here or in
11// syscall_solaris.go or syscall_unix.go.
12
13package unix
14
15import (
16	"syscall"
17	"unsafe"
18)
19
20// Implemented in runtime/syscall_solaris.go.
21type syscallFunc uintptr
22
23func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
24func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
25
26// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
27type SockaddrDatalink struct {
28	Family uint16
29	Index  uint16
30	Type   uint8
31	Nlen   uint8
32	Alen   uint8
33	Slen   uint8
34	Data   [244]int8
35	raw    RawSockaddrDatalink
36}
37
38//sysnb	pipe(p *[2]_C_int) (n int, err error)
39
40func Pipe(p []int) (err error) {
41	if len(p) != 2 {
42		return EINVAL
43	}
44	var pp [2]_C_int
45	n, err := pipe(&pp)
46	if n != 0 {
47		return err
48	}
49	p[0] = int(pp[0])
50	p[1] = int(pp[1])
51	return nil
52}
53
54func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
55	if sa.Port < 0 || sa.Port > 0xFFFF {
56		return nil, 0, EINVAL
57	}
58	sa.raw.Family = AF_INET
59	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
60	p[0] = byte(sa.Port >> 8)
61	p[1] = byte(sa.Port)
62	for i := 0; i < len(sa.Addr); i++ {
63		sa.raw.Addr[i] = sa.Addr[i]
64	}
65	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
66}
67
68func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
69	if sa.Port < 0 || sa.Port > 0xFFFF {
70		return nil, 0, EINVAL
71	}
72	sa.raw.Family = AF_INET6
73	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
74	p[0] = byte(sa.Port >> 8)
75	p[1] = byte(sa.Port)
76	sa.raw.Scope_id = sa.ZoneId
77	for i := 0; i < len(sa.Addr); i++ {
78		sa.raw.Addr[i] = sa.Addr[i]
79	}
80	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
81}
82
83func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
84	name := sa.Name
85	n := len(name)
86	if n >= len(sa.raw.Path) {
87		return nil, 0, EINVAL
88	}
89	sa.raw.Family = AF_UNIX
90	for i := 0; i < n; i++ {
91		sa.raw.Path[i] = int8(name[i])
92	}
93	// length is family (uint16), name, NUL.
94	sl := _Socklen(2)
95	if n > 0 {
96		sl += _Socklen(n) + 1
97	}
98	if sa.raw.Path[0] == '@' {
99		sa.raw.Path[0] = 0
100		// Don't count trailing NUL for abstract address.
101		sl--
102	}
103
104	return unsafe.Pointer(&sa.raw), sl, nil
105}
106
107//sys	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname
108
109func Getsockname(fd int) (sa Sockaddr, err error) {
110	var rsa RawSockaddrAny
111	var len _Socklen = SizeofSockaddrAny
112	if err = getsockname(fd, &rsa, &len); err != nil {
113		return
114	}
115	return anyToSockaddr(&rsa)
116}
117
118// GetsockoptString returns the string value of the socket option opt for the
119// socket associated with fd at the given socket level.
120func GetsockoptString(fd, level, opt int) (string, error) {
121	buf := make([]byte, 256)
122	vallen := _Socklen(len(buf))
123	err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
124	if err != nil {
125		return "", err
126	}
127	return string(buf[:vallen-1]), nil
128}
129
130const ImplementsGetwd = true
131
132//sys	Getcwd(buf []byte) (n int, err error)
133
134func Getwd() (wd string, err error) {
135	var buf [PathMax]byte
136	// Getcwd will return an error if it failed for any reason.
137	_, err = Getcwd(buf[0:])
138	if err != nil {
139		return "", err
140	}
141	n := clen(buf[:])
142	if n < 1 {
143		return "", EINVAL
144	}
145	return string(buf[:n]), nil
146}
147
148/*
149 * Wrapped
150 */
151
152//sysnb	getgroups(ngid int, gid *_Gid_t) (n int, err error)
153//sysnb	setgroups(ngid int, gid *_Gid_t) (err error)
154
155func Getgroups() (gids []int, err error) {
156	n, err := getgroups(0, nil)
157	// Check for error and sanity check group count. Newer versions of
158	// Solaris allow up to 1024 (NGROUPS_MAX).
159	if n < 0 || n > 1024 {
160		if err != nil {
161			return nil, err
162		}
163		return nil, EINVAL
164	} else if n == 0 {
165		return nil, nil
166	}
167
168	a := make([]_Gid_t, n)
169	n, err = getgroups(n, &a[0])
170	if n == -1 {
171		return nil, err
172	}
173	gids = make([]int, n)
174	for i, v := range a[0:n] {
175		gids[i] = int(v)
176	}
177	return
178}
179
180func Setgroups(gids []int) (err error) {
181	if len(gids) == 0 {
182		return setgroups(0, nil)
183	}
184
185	a := make([]_Gid_t, len(gids))
186	for i, v := range gids {
187		a[i] = _Gid_t(v)
188	}
189	return setgroups(len(a), &a[0])
190}
191
192func ReadDirent(fd int, buf []byte) (n int, err error) {
193	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
194	// TODO(rsc): Can we use a single global basep for all calls?
195	return Getdents(fd, buf, new(uintptr))
196}
197
198// Wait status is 7 bits at bottom, either 0 (exited),
199// 0x7F (stopped), or a signal number that caused an exit.
200// The 0x80 bit is whether there was a core dump.
201// An extra number (exit code, signal causing a stop)
202// is in the high bits.
203
204type WaitStatus uint32
205
206const (
207	mask  = 0x7F
208	core  = 0x80
209	shift = 8
210
211	exited  = 0
212	stopped = 0x7F
213)
214
215func (w WaitStatus) Exited() bool { return w&mask == exited }
216
217func (w WaitStatus) ExitStatus() int {
218	if w&mask != exited {
219		return -1
220	}
221	return int(w >> shift)
222}
223
224func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
225
226func (w WaitStatus) Signal() syscall.Signal {
227	sig := syscall.Signal(w & mask)
228	if sig == stopped || sig == 0 {
229		return -1
230	}
231	return sig
232}
233
234func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
235
236func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP }
237
238func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP }
239
240func (w WaitStatus) StopSignal() syscall.Signal {
241	if !w.Stopped() {
242		return -1
243	}
244	return syscall.Signal(w>>shift) & 0xFF
245}
246
247func (w WaitStatus) TrapCause() int { return -1 }
248
249//sys	wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error)
250
251func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (int, error) {
252	var status _C_int
253	rpid, err := wait4(int32(pid), &status, options, rusage)
254	wpid := int(rpid)
255	if wpid == -1 {
256		return wpid, err
257	}
258	if wstatus != nil {
259		*wstatus = WaitStatus(status)
260	}
261	return wpid, nil
262}
263
264//sys	gethostname(buf []byte) (n int, err error)
265
266func Gethostname() (name string, err error) {
267	var buf [MaxHostNameLen]byte
268	n, err := gethostname(buf[:])
269	if n != 0 {
270		return "", err
271	}
272	n = clen(buf[:])
273	if n < 1 {
274		return "", EFAULT
275	}
276	return string(buf[:n]), nil
277}
278
279//sys	utimes(path string, times *[2]Timeval) (err error)
280
281func Utimes(path string, tv []Timeval) (err error) {
282	if tv == nil {
283		return utimes(path, nil)
284	}
285	if len(tv) != 2 {
286		return EINVAL
287	}
288	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
289}
290
291//sys	utimensat(fd int, path string, times *[2]Timespec, flag int) (err error)
292
293func UtimesNano(path string, ts []Timespec) error {
294	if ts == nil {
295		return utimensat(AT_FDCWD, path, nil, 0)
296	}
297	if len(ts) != 2 {
298		return EINVAL
299	}
300	return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
301}
302
303func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
304	if ts == nil {
305		return utimensat(dirfd, path, nil, flags)
306	}
307	if len(ts) != 2 {
308		return EINVAL
309	}
310	return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
311}
312
313//sys	fcntl(fd int, cmd int, arg int) (val int, err error)
314
315// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
316func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
317	valptr, _, err := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
318	return int(valptr), err
319}
320
321// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
322func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
323	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
324	if e1 != 0 {
325		return e1
326	}
327	return nil
328}
329
330//sys	futimesat(fildes int, path *byte, times *[2]Timeval) (err error)
331
332func Futimesat(dirfd int, path string, tv []Timeval) error {
333	pathp, err := BytePtrFromString(path)
334	if err != nil {
335		return err
336	}
337	if tv == nil {
338		return futimesat(dirfd, pathp, nil)
339	}
340	if len(tv) != 2 {
341		return EINVAL
342	}
343	return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
344}
345
346// Solaris doesn't have an futimes function because it allows NULL to be
347// specified as the path for futimesat. However, Go doesn't like
348// NULL-style string interfaces, so this simple wrapper is provided.
349func Futimes(fd int, tv []Timeval) error {
350	if tv == nil {
351		return futimesat(fd, nil, nil)
352	}
353	if len(tv) != 2 {
354		return EINVAL
355	}
356	return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
357}
358
359func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
360	switch rsa.Addr.Family {
361	case AF_UNIX:
362		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
363		sa := new(SockaddrUnix)
364		// Assume path ends at NUL.
365		// This is not technically the Solaris semantics for
366		// abstract Unix domain sockets -- they are supposed
367		// to be uninterpreted fixed-size binary blobs -- but
368		// everyone uses this convention.
369		n := 0
370		for n < len(pp.Path) && pp.Path[n] != 0 {
371			n++
372		}
373		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
374		sa.Name = string(bytes)
375		return sa, nil
376
377	case AF_INET:
378		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
379		sa := new(SockaddrInet4)
380		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
381		sa.Port = int(p[0])<<8 + int(p[1])
382		for i := 0; i < len(sa.Addr); i++ {
383			sa.Addr[i] = pp.Addr[i]
384		}
385		return sa, nil
386
387	case AF_INET6:
388		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
389		sa := new(SockaddrInet6)
390		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
391		sa.Port = int(p[0])<<8 + int(p[1])
392		sa.ZoneId = pp.Scope_id
393		for i := 0; i < len(sa.Addr); i++ {
394			sa.Addr[i] = pp.Addr[i]
395		}
396		return sa, nil
397	}
398	return nil, EAFNOSUPPORT
399}
400
401//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libsocket.accept
402
403func Accept(fd int) (nfd int, sa Sockaddr, err error) {
404	var rsa RawSockaddrAny
405	var len _Socklen = SizeofSockaddrAny
406	nfd, err = accept(fd, &rsa, &len)
407	if nfd == -1 {
408		return
409	}
410	sa, err = anyToSockaddr(&rsa)
411	if err != nil {
412		Close(nfd)
413		nfd = 0
414	}
415	return
416}
417
418//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg
419
420func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
421	var msg Msghdr
422	var rsa RawSockaddrAny
423	msg.Name = (*byte)(unsafe.Pointer(&rsa))
424	msg.Namelen = uint32(SizeofSockaddrAny)
425	var iov Iovec
426	if len(p) > 0 {
427		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
428		iov.SetLen(len(p))
429	}
430	var dummy int8
431	if len(oob) > 0 {
432		// receive at least one normal byte
433		if len(p) == 0 {
434			iov.Base = &dummy
435			iov.SetLen(1)
436		}
437		msg.Accrightslen = int32(len(oob))
438	}
439	msg.Iov = &iov
440	msg.Iovlen = 1
441	if n, err = recvmsg(fd, &msg, flags); n == -1 {
442		return
443	}
444	oobn = int(msg.Accrightslen)
445	// source address is only specified if the socket is unconnected
446	if rsa.Addr.Family != AF_UNSPEC {
447		from, err = anyToSockaddr(&rsa)
448	}
449	return
450}
451
452func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
453	_, err = SendmsgN(fd, p, oob, to, flags)
454	return
455}
456
457//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg
458
459func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
460	var ptr unsafe.Pointer
461	var salen _Socklen
462	if to != nil {
463		ptr, salen, err = to.sockaddr()
464		if err != nil {
465			return 0, err
466		}
467	}
468	var msg Msghdr
469	msg.Name = (*byte)(unsafe.Pointer(ptr))
470	msg.Namelen = uint32(salen)
471	var iov Iovec
472	if len(p) > 0 {
473		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
474		iov.SetLen(len(p))
475	}
476	var dummy int8
477	if len(oob) > 0 {
478		// send at least one normal byte
479		if len(p) == 0 {
480			iov.Base = &dummy
481			iov.SetLen(1)
482		}
483		msg.Accrightslen = int32(len(oob))
484	}
485	msg.Iov = &iov
486	msg.Iovlen = 1
487	if n, err = sendmsg(fd, &msg, flags); err != nil {
488		return 0, err
489	}
490	if len(oob) > 0 && len(p) == 0 {
491		n = 0
492	}
493	return n, nil
494}
495
496//sys	acct(path *byte) (err error)
497
498func Acct(path string) (err error) {
499	if len(path) == 0 {
500		// Assume caller wants to disable accounting.
501		return acct(nil)
502	}
503
504	pathp, err := BytePtrFromString(path)
505	if err != nil {
506		return err
507	}
508	return acct(pathp)
509}
510
511//sys	__makedev(version int, major uint, minor uint) (val uint64)
512
513func Mkdev(major, minor uint32) uint64 {
514	return __makedev(NEWDEV, uint(major), uint(minor))
515}
516
517//sys	__major(version int, dev uint64) (val uint)
518
519func Major(dev uint64) uint32 {
520	return uint32(__major(NEWDEV, dev))
521}
522
523//sys	__minor(version int, dev uint64) (val uint)
524
525func Minor(dev uint64) uint32 {
526	return uint32(__minor(NEWDEV, dev))
527}
528
529/*
530 * Expose the ioctl function
531 */
532
533//sys	ioctl(fd int, req uint, arg uintptr) (err error)
534
535func IoctlSetInt(fd int, req uint, value int) (err error) {
536	return ioctl(fd, req, uintptr(value))
537}
538
539func IoctlSetWinsize(fd int, req uint, value *Winsize) (err error) {
540	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
541}
542
543func IoctlSetTermios(fd int, req uint, value *Termios) (err error) {
544	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
545}
546
547func IoctlSetTermio(fd int, req uint, value *Termio) (err error) {
548	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
549}
550
551func IoctlGetInt(fd int, req uint) (int, error) {
552	var value int
553	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
554	return value, err
555}
556
557func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
558	var value Winsize
559	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
560	return &value, err
561}
562
563func IoctlGetTermios(fd int, req uint) (*Termios, error) {
564	var value Termios
565	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
566	return &value, err
567}
568
569func IoctlGetTermio(fd int, req uint) (*Termio, error) {
570	var value Termio
571	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
572	return &value, err
573}
574
575//sys   poll(fds *PollFd, nfds int, timeout int) (n int, err error)
576
577func Poll(fds []PollFd, timeout int) (n int, err error) {
578	if len(fds) == 0 {
579		return poll(nil, 0, timeout)
580	}
581	return poll(&fds[0], len(fds), timeout)
582}
583
584/*
585 * Exposed directly
586 */
587//sys	Access(path string, mode uint32) (err error)
588//sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
589//sys	Chdir(path string) (err error)
590//sys	Chmod(path string, mode uint32) (err error)
591//sys	Chown(path string, uid int, gid int) (err error)
592//sys	Chroot(path string) (err error)
593//sys	Close(fd int) (err error)
594//sys	Creat(path string, mode uint32) (fd int, err error)
595//sys	Dup(fd int) (nfd int, err error)
596//sys	Dup2(oldfd int, newfd int) (err error)
597//sys	Exit(code int)
598//sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
599//sys	Fchdir(fd int) (err error)
600//sys	Fchmod(fd int, mode uint32) (err error)
601//sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
602//sys	Fchown(fd int, uid int, gid int) (err error)
603//sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
604//sys	Fdatasync(fd int) (err error)
605//sys	Flock(fd int, how int) (err error)
606//sys	Fpathconf(fd int, name int) (val int, err error)
607//sys	Fstat(fd int, stat *Stat_t) (err error)
608//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
609//sys	Fstatvfs(fd int, vfsstat *Statvfs_t) (err error)
610//sys	Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
611//sysnb	Getgid() (gid int)
612//sysnb	Getpid() (pid int)
613//sysnb	Getpgid(pid int) (pgid int, err error)
614//sysnb	Getpgrp() (pgid int, err error)
615//sys	Geteuid() (euid int)
616//sys	Getegid() (egid int)
617//sys	Getppid() (ppid int)
618//sys	Getpriority(which int, who int) (n int, err error)
619//sysnb	Getrlimit(which int, lim *Rlimit) (err error)
620//sysnb	Getrusage(who int, rusage *Rusage) (err error)
621//sysnb	Gettimeofday(tv *Timeval) (err error)
622//sysnb	Getuid() (uid int)
623//sys	Kill(pid int, signum syscall.Signal) (err error)
624//sys	Lchown(path string, uid int, gid int) (err error)
625//sys	Link(path string, link string) (err error)
626//sys	Listen(s int, backlog int) (err error) = libsocket.__xnet_llisten
627//sys	Lstat(path string, stat *Stat_t) (err error)
628//sys	Madvise(b []byte, advice int) (err error)
629//sys	Mkdir(path string, mode uint32) (err error)
630//sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
631//sys	Mkfifo(path string, mode uint32) (err error)
632//sys	Mkfifoat(dirfd int, path string, mode uint32) (err error)
633//sys	Mknod(path string, mode uint32, dev int) (err error)
634//sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
635//sys	Mlock(b []byte) (err error)
636//sys	Mlockall(flags int) (err error)
637//sys	Mprotect(b []byte, prot int) (err error)
638//sys	Msync(b []byte, flags int) (err error)
639//sys	Munlock(b []byte) (err error)
640//sys	Munlockall() (err error)
641//sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
642//sys	Open(path string, mode int, perm uint32) (fd int, err error)
643//sys	Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
644//sys	Pathconf(path string, name int) (val int, err error)
645//sys	Pause() (err error)
646//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
647//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
648//sys	read(fd int, p []byte) (n int, err error)
649//sys	Readlink(path string, buf []byte) (n int, err error)
650//sys	Rename(from string, to string) (err error)
651//sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
652//sys	Rmdir(path string) (err error)
653//sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
654//sys	Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
655//sysnb	Setegid(egid int) (err error)
656//sysnb	Seteuid(euid int) (err error)
657//sysnb	Setgid(gid int) (err error)
658//sys	Sethostname(p []byte) (err error)
659//sysnb	Setpgid(pid int, pgid int) (err error)
660//sys	Setpriority(which int, who int, prio int) (err error)
661//sysnb	Setregid(rgid int, egid int) (err error)
662//sysnb	Setreuid(ruid int, euid int) (err error)
663//sysnb	Setrlimit(which int, lim *Rlimit) (err error)
664//sysnb	Setsid() (pid int, err error)
665//sysnb	Setuid(uid int) (err error)
666//sys	Shutdown(s int, how int) (err error) = libsocket.shutdown
667//sys	Stat(path string, stat *Stat_t) (err error)
668//sys	Statvfs(path string, vfsstat *Statvfs_t) (err error)
669//sys	Symlink(path string, link string) (err error)
670//sys	Sync() (err error)
671//sysnb	Times(tms *Tms) (ticks uintptr, err error)
672//sys	Truncate(path string, length int64) (err error)
673//sys	Fsync(fd int) (err error)
674//sys	Ftruncate(fd int, length int64) (err error)
675//sys	Umask(mask int) (oldmask int)
676//sysnb	Uname(buf *Utsname) (err error)
677//sys	Unmount(target string, flags int) (err error) = libc.umount
678//sys	Unlink(path string) (err error)
679//sys	Unlinkat(dirfd int, path string, flags int) (err error)
680//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
681//sys	Utime(path string, buf *Utimbuf) (err error)
682//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_bind
683//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect
684//sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
685//sys	munmap(addr uintptr, length uintptr) (err error)
686//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile
687//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto
688//sys	socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket
689//sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair
690//sys	write(fd int, p []byte) (n int, err error)
691//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.__xnet_getsockopt
692//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername
693//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt
694//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom
695
696func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
697	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procread)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
698	n = int(r0)
699	if e1 != 0 {
700		err = e1
701	}
702	return
703}
704
705func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
706	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwrite)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
707	n = int(r0)
708	if e1 != 0 {
709		err = e1
710	}
711	return
712}
713
714var mapper = &mmapper{
715	active: make(map[*byte][]byte),
716	mmap:   mmap,
717	munmap: munmap,
718}
719
720func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
721	return mapper.Mmap(fd, offset, length, prot, flags)
722}
723
724func Munmap(b []byte) (err error) {
725	return mapper.Munmap(b)
726}
727