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(fd, &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, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
318	var err error
319	if errno != 0 {
320		err = errno
321	}
322	return int(valptr), err
323}
324
325// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
326func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
327	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
328	if e1 != 0 {
329		return e1
330	}
331	return nil
332}
333
334//sys	futimesat(fildes int, path *byte, times *[2]Timeval) (err error)
335
336func Futimesat(dirfd int, path string, tv []Timeval) error {
337	pathp, err := BytePtrFromString(path)
338	if err != nil {
339		return err
340	}
341	if tv == nil {
342		return futimesat(dirfd, pathp, nil)
343	}
344	if len(tv) != 2 {
345		return EINVAL
346	}
347	return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
348}
349
350// Solaris doesn't have an futimes function because it allows NULL to be
351// specified as the path for futimesat. However, Go doesn't like
352// NULL-style string interfaces, so this simple wrapper is provided.
353func Futimes(fd int, tv []Timeval) error {
354	if tv == nil {
355		return futimesat(fd, nil, nil)
356	}
357	if len(tv) != 2 {
358		return EINVAL
359	}
360	return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
361}
362
363func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
364	switch rsa.Addr.Family {
365	case AF_UNIX:
366		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
367		sa := new(SockaddrUnix)
368		// Assume path ends at NUL.
369		// This is not technically the Solaris semantics for
370		// abstract Unix domain sockets -- they are supposed
371		// to be uninterpreted fixed-size binary blobs -- but
372		// everyone uses this convention.
373		n := 0
374		for n < len(pp.Path) && pp.Path[n] != 0 {
375			n++
376		}
377		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
378		sa.Name = string(bytes)
379		return sa, nil
380
381	case AF_INET:
382		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
383		sa := new(SockaddrInet4)
384		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
385		sa.Port = int(p[0])<<8 + int(p[1])
386		for i := 0; i < len(sa.Addr); i++ {
387			sa.Addr[i] = pp.Addr[i]
388		}
389		return sa, nil
390
391	case AF_INET6:
392		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
393		sa := new(SockaddrInet6)
394		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
395		sa.Port = int(p[0])<<8 + int(p[1])
396		sa.ZoneId = pp.Scope_id
397		for i := 0; i < len(sa.Addr); i++ {
398			sa.Addr[i] = pp.Addr[i]
399		}
400		return sa, nil
401	}
402	return nil, EAFNOSUPPORT
403}
404
405//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libsocket.accept
406
407func Accept(fd int) (nfd int, sa Sockaddr, err error) {
408	var rsa RawSockaddrAny
409	var len _Socklen = SizeofSockaddrAny
410	nfd, err = accept(fd, &rsa, &len)
411	if nfd == -1 {
412		return
413	}
414	sa, err = anyToSockaddr(fd, &rsa)
415	if err != nil {
416		Close(nfd)
417		nfd = 0
418	}
419	return
420}
421
422//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg
423
424func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
425	var msg Msghdr
426	var rsa RawSockaddrAny
427	msg.Name = (*byte)(unsafe.Pointer(&rsa))
428	msg.Namelen = uint32(SizeofSockaddrAny)
429	var iov Iovec
430	if len(p) > 0 {
431		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
432		iov.SetLen(len(p))
433	}
434	var dummy int8
435	if len(oob) > 0 {
436		// receive at least one normal byte
437		if len(p) == 0 {
438			iov.Base = &dummy
439			iov.SetLen(1)
440		}
441		msg.Accrightslen = int32(len(oob))
442	}
443	msg.Iov = &iov
444	msg.Iovlen = 1
445	if n, err = recvmsg(fd, &msg, flags); n == -1 {
446		return
447	}
448	oobn = int(msg.Accrightslen)
449	// source address is only specified if the socket is unconnected
450	if rsa.Addr.Family != AF_UNSPEC {
451		from, err = anyToSockaddr(fd, &rsa)
452	}
453	return
454}
455
456func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
457	_, err = SendmsgN(fd, p, oob, to, flags)
458	return
459}
460
461//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg
462
463func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
464	var ptr unsafe.Pointer
465	var salen _Socklen
466	if to != nil {
467		ptr, salen, err = to.sockaddr()
468		if err != nil {
469			return 0, err
470		}
471	}
472	var msg Msghdr
473	msg.Name = (*byte)(unsafe.Pointer(ptr))
474	msg.Namelen = uint32(salen)
475	var iov Iovec
476	if len(p) > 0 {
477		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
478		iov.SetLen(len(p))
479	}
480	var dummy int8
481	if len(oob) > 0 {
482		// send at least one normal byte
483		if len(p) == 0 {
484			iov.Base = &dummy
485			iov.SetLen(1)
486		}
487		msg.Accrightslen = int32(len(oob))
488	}
489	msg.Iov = &iov
490	msg.Iovlen = 1
491	if n, err = sendmsg(fd, &msg, flags); err != nil {
492		return 0, err
493	}
494	if len(oob) > 0 && len(p) == 0 {
495		n = 0
496	}
497	return n, nil
498}
499
500//sys	acct(path *byte) (err error)
501
502func Acct(path string) (err error) {
503	if len(path) == 0 {
504		// Assume caller wants to disable accounting.
505		return acct(nil)
506	}
507
508	pathp, err := BytePtrFromString(path)
509	if err != nil {
510		return err
511	}
512	return acct(pathp)
513}
514
515//sys	__makedev(version int, major uint, minor uint) (val uint64)
516
517func Mkdev(major, minor uint32) uint64 {
518	return __makedev(NEWDEV, uint(major), uint(minor))
519}
520
521//sys	__major(version int, dev uint64) (val uint)
522
523func Major(dev uint64) uint32 {
524	return uint32(__major(NEWDEV, dev))
525}
526
527//sys	__minor(version int, dev uint64) (val uint)
528
529func Minor(dev uint64) uint32 {
530	return uint32(__minor(NEWDEV, dev))
531}
532
533/*
534 * Expose the ioctl function
535 */
536
537//sys	ioctl(fd int, req uint, arg uintptr) (err error)
538
539func IoctlSetInt(fd int, req uint, value int) (err error) {
540	return ioctl(fd, req, uintptr(value))
541}
542
543func ioctlSetWinsize(fd int, req uint, value *Winsize) (err error) {
544	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
545}
546
547func ioctlSetTermios(fd int, req uint, value *Termios) (err error) {
548	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
549}
550
551func IoctlSetTermio(fd int, req uint, value *Termio) (err error) {
552	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
553}
554
555func IoctlGetInt(fd int, req uint) (int, error) {
556	var value int
557	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
558	return value, err
559}
560
561func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
562	var value Winsize
563	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
564	return &value, err
565}
566
567func IoctlGetTermios(fd int, req uint) (*Termios, error) {
568	var value Termios
569	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
570	return &value, err
571}
572
573func IoctlGetTermio(fd int, req uint) (*Termio, error) {
574	var value Termio
575	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
576	return &value, err
577}
578
579//sys   poll(fds *PollFd, nfds int, timeout int) (n int, err error)
580
581func Poll(fds []PollFd, timeout int) (n int, err error) {
582	if len(fds) == 0 {
583		return poll(nil, 0, timeout)
584	}
585	return poll(&fds[0], len(fds), timeout)
586}
587
588/*
589 * Exposed directly
590 */
591//sys	Access(path string, mode uint32) (err error)
592//sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
593//sys	Chdir(path string) (err error)
594//sys	Chmod(path string, mode uint32) (err error)
595//sys	Chown(path string, uid int, gid int) (err error)
596//sys	Chroot(path string) (err error)
597//sys	Close(fd int) (err error)
598//sys	Creat(path string, mode uint32) (fd int, err error)
599//sys	Dup(fd int) (nfd int, err error)
600//sys	Dup2(oldfd int, newfd int) (err error)
601//sys	Exit(code int)
602//sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
603//sys	Fchdir(fd int) (err error)
604//sys	Fchmod(fd int, mode uint32) (err error)
605//sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
606//sys	Fchown(fd int, uid int, gid int) (err error)
607//sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
608//sys	Fdatasync(fd int) (err error)
609//sys	Flock(fd int, how int) (err error)
610//sys	Fpathconf(fd int, name int) (val int, err error)
611//sys	Fstat(fd int, stat *Stat_t) (err error)
612//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
613//sys	Fstatvfs(fd int, vfsstat *Statvfs_t) (err error)
614//sys	Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
615//sysnb	Getgid() (gid int)
616//sysnb	Getpid() (pid int)
617//sysnb	Getpgid(pid int) (pgid int, err error)
618//sysnb	Getpgrp() (pgid int, err error)
619//sys	Geteuid() (euid int)
620//sys	Getegid() (egid int)
621//sys	Getppid() (ppid int)
622//sys	Getpriority(which int, who int) (n int, err error)
623//sysnb	Getrlimit(which int, lim *Rlimit) (err error)
624//sysnb	Getrusage(who int, rusage *Rusage) (err error)
625//sysnb	Gettimeofday(tv *Timeval) (err error)
626//sysnb	Getuid() (uid int)
627//sys	Kill(pid int, signum syscall.Signal) (err error)
628//sys	Lchown(path string, uid int, gid int) (err error)
629//sys	Link(path string, link string) (err error)
630//sys	Listen(s int, backlog int) (err error) = libsocket.__xnet_llisten
631//sys	Lstat(path string, stat *Stat_t) (err error)
632//sys	Madvise(b []byte, advice int) (err error)
633//sys	Mkdir(path string, mode uint32) (err error)
634//sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
635//sys	Mkfifo(path string, mode uint32) (err error)
636//sys	Mkfifoat(dirfd int, path string, mode uint32) (err error)
637//sys	Mknod(path string, mode uint32, dev int) (err error)
638//sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
639//sys	Mlock(b []byte) (err error)
640//sys	Mlockall(flags int) (err error)
641//sys	Mprotect(b []byte, prot int) (err error)
642//sys	Msync(b []byte, flags int) (err error)
643//sys	Munlock(b []byte) (err error)
644//sys	Munlockall() (err error)
645//sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
646//sys	Open(path string, mode int, perm uint32) (fd int, err error)
647//sys	Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
648//sys	Pathconf(path string, name int) (val int, err error)
649//sys	Pause() (err error)
650//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
651//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
652//sys	read(fd int, p []byte) (n int, err error)
653//sys	Readlink(path string, buf []byte) (n int, err error)
654//sys	Rename(from string, to string) (err error)
655//sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
656//sys	Rmdir(path string) (err error)
657//sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
658//sys	Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
659//sysnb	Setegid(egid int) (err error)
660//sysnb	Seteuid(euid int) (err error)
661//sysnb	Setgid(gid int) (err error)
662//sys	Sethostname(p []byte) (err error)
663//sysnb	Setpgid(pid int, pgid int) (err error)
664//sys	Setpriority(which int, who int, prio int) (err error)
665//sysnb	Setregid(rgid int, egid int) (err error)
666//sysnb	Setreuid(ruid int, euid int) (err error)
667//sysnb	Setrlimit(which int, lim *Rlimit) (err error)
668//sysnb	Setsid() (pid int, err error)
669//sysnb	Setuid(uid int) (err error)
670//sys	Shutdown(s int, how int) (err error) = libsocket.shutdown
671//sys	Stat(path string, stat *Stat_t) (err error)
672//sys	Statvfs(path string, vfsstat *Statvfs_t) (err error)
673//sys	Symlink(path string, link string) (err error)
674//sys	Sync() (err error)
675//sysnb	Times(tms *Tms) (ticks uintptr, err error)
676//sys	Truncate(path string, length int64) (err error)
677//sys	Fsync(fd int) (err error)
678//sys	Ftruncate(fd int, length int64) (err error)
679//sys	Umask(mask int) (oldmask int)
680//sysnb	Uname(buf *Utsname) (err error)
681//sys	Unmount(target string, flags int) (err error) = libc.umount
682//sys	Unlink(path string) (err error)
683//sys	Unlinkat(dirfd int, path string, flags int) (err error)
684//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
685//sys	Utime(path string, buf *Utimbuf) (err error)
686//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_bind
687//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect
688//sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
689//sys	munmap(addr uintptr, length uintptr) (err error)
690//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile
691//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto
692//sys	socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket
693//sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair
694//sys	write(fd int, p []byte) (n int, err error)
695//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.__xnet_getsockopt
696//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername
697//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt
698//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom
699
700func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
701	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procread)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
702	n = int(r0)
703	if e1 != 0 {
704		err = e1
705	}
706	return
707}
708
709func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
710	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwrite)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
711	n = int(r0)
712	if e1 != 0 {
713		err = e1
714	}
715	return
716}
717
718var mapper = &mmapper{
719	active: make(map[*byte][]byte),
720	mmap:   mmap,
721	munmap: munmap,
722}
723
724func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
725	return mapper.Mmap(fd, offset, length, prot, flags)
726}
727
728func Munmap(b []byte) (err error) {
729	return mapper.Munmap(b)
730}
731