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