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