OSDN Git Service

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