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