]> Cypherpunks.ru repositories - gostls13.git/blob - src/syscall/syscall_aix.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / syscall / syscall_aix.go
1 // Copyright 2018 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 // Aix 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
10 // wrap it in our own nicer implementation.
11
12 package syscall
13
14 import (
15         "unsafe"
16 )
17
18 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
19 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
20 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
21 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
22
23 // Implemented in runtime/syscall_aix.go.
24 func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
25 func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
26
27 // Constant expected by package but not supported
28 const (
29         _ = iota
30         TIOCSCTTY
31         SYS_EXECVE
32         SYS_FCNTL
33 )
34
35 const (
36         F_DUPFD_CLOEXEC = 0
37         // AF_LOCAL doesn't exist on AIX
38         AF_LOCAL = AF_UNIX
39
40         _F_DUP2FD_CLOEXEC = 0
41 )
42
43 func (ts *StTimespec_t) Unix() (sec int64, nsec int64) {
44         return int64(ts.Sec), int64(ts.Nsec)
45 }
46
47 func (ts *StTimespec_t) Nano() int64 {
48         return int64(ts.Sec)*1e9 + int64(ts.Nsec)
49 }
50
51 /*
52  * Wrapped
53  */
54
55 func Access(path string, mode uint32) (err error) {
56         return Faccessat(_AT_FDCWD, path, mode, 0)
57 }
58
59 // fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX
60 // There is no way to create a custom fcntl and to keep //sys fcntl easily,
61 // because we need fcntl name for its libc symbol. This is linked with the script.
62 // But, as fcntl is currently not exported and isn't called with F_DUP2FD,
63 // it doesn't matter.
64 //sys   fcntl(fd int, cmd int, arg int) (val int, err error)
65 //sys   Dup2(old int, new int) (err error)
66
67 //sysnb pipe(p *[2]_C_int) (err error)
68
69 func Pipe(p []int) (err error) {
70         if len(p) != 2 {
71                 return EINVAL
72         }
73         var pp [2]_C_int
74         err = pipe(&pp)
75         if err == nil {
76                 p[0] = int(pp[0])
77                 p[1] = int(pp[1])
78         }
79         return
80 }
81
82 //sys   readlink(path string, buf []byte, bufSize uint64) (n int, err error)
83
84 func Readlink(path string, buf []byte) (n int, err error) {
85         s := uint64(len(buf))
86         return readlink(path, buf, s)
87 }
88
89 //sys   utimes(path string, times *[2]Timeval) (err error)
90
91 func Utimes(path string, tv []Timeval) error {
92         if len(tv) != 2 {
93                 return EINVAL
94         }
95         return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
96 }
97
98 //sys   utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
99
100 func UtimesNano(path string, ts []Timespec) error {
101         if len(ts) != 2 {
102                 return EINVAL
103         }
104         return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
105 }
106
107 //sys   unlinkat(dirfd int, path string, flags int) (err error)
108
109 func Unlinkat(dirfd int, path string) (err error) {
110         return unlinkat(dirfd, path, 0)
111 }
112
113 //sys   getcwd(buf *byte, size uint64) (err error)
114
115 const ImplementsGetwd = true
116
117 func Getwd() (ret string, err error) {
118         for len := uint64(4096); ; len *= 2 {
119                 b := make([]byte, len)
120                 err := getcwd(&b[0], len)
121                 if err == nil {
122                         i := 0
123                         for b[i] != 0 {
124                                 i++
125                         }
126                         return string(b[0:i]), nil
127                 }
128                 if err != ERANGE {
129                         return "", err
130                 }
131         }
132 }
133
134 func Getcwd(buf []byte) (n int, err error) {
135         err = getcwd(&buf[0], uint64(len(buf)))
136         if err == nil {
137                 i := 0
138                 for buf[i] != 0 {
139                         i++
140                 }
141                 n = i + 1
142         }
143         return
144 }
145
146 //sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error)
147 //sysnb setgroups(ngid int, gid *_Gid_t) (err error)
148
149 func Getgroups() (gids []int, err error) {
150         n, err := getgroups(0, nil)
151         if err != nil {
152                 return nil, err
153         }
154         if n == 0 {
155                 return nil, nil
156         }
157
158         // Sanity check group count. Max is 16 on BSD.
159         if n < 0 || n > 1000 {
160                 return nil, EINVAL
161         }
162
163         a := make([]_Gid_t, n)
164         n, err = getgroups(n, &a[0])
165         if err != nil {
166                 return nil, err
167         }
168         gids = make([]int, n)
169         for i, v := range a[0:n] {
170                 gids[i] = int(v)
171         }
172         return
173 }
174
175 func Setgroups(gids []int) (err error) {
176         if len(gids) == 0 {
177                 return setgroups(0, nil)
178         }
179
180         a := make([]_Gid_t, len(gids))
181         for i, v := range gids {
182                 a[i] = _Gid_t(v)
183         }
184         return setgroups(len(a), &a[0])
185 }
186
187 func direntIno(buf []byte) (uint64, bool) {
188         return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
189 }
190
191 func direntReclen(buf []byte) (uint64, bool) {
192         return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
193 }
194
195 func direntNamlen(buf []byte) (uint64, bool) {
196         reclen, ok := direntReclen(buf)
197         if !ok {
198                 return 0, false
199         }
200         return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
201 }
202
203 func Gettimeofday(tv *Timeval) (err error) {
204         err = gettimeofday(tv, nil)
205         return
206 }
207
208 // TODO
209 func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
210         return -1, ENOSYS
211 }
212
213 //sys   getdirent(fd int, buf []byte) (n int, err error)
214
215 func ReadDirent(fd int, buf []byte) (n int, err error) {
216         return getdirent(fd, buf)
217 }
218
219 //sys  wait4(pid _Pid_t, status *_C_int, options int, rusage *Rusage) (wpid _Pid_t, err error)
220
221 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
222         var status _C_int
223         var r _Pid_t
224         err = ERESTART
225         // AIX wait4 may return with ERESTART errno, while the processus is still
226         // active.
227         for err == ERESTART {
228                 r, err = wait4(_Pid_t(pid), &status, options, rusage)
229         }
230         wpid = int(r)
231         if wstatus != nil {
232                 *wstatus = WaitStatus(status)
233         }
234         return
235 }
236
237 //sys   fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range
238
239 func Fsync(fd int) error {
240         return fsyncRange(fd, O_SYNC, 0, 0)
241 }
242
243 /*
244  * Socket
245  */
246 //sys   bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
247 //sys   connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
248 //sys   Getkerninfo(op int32, where uintptr, size uintptr, arg int64) (i int32, err error)
249 //sys   getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
250 //sys   Listen(s int, backlog int) (err error)
251 //sys   setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
252 //sys   socket(domain int, typ int, proto int) (fd int, err error)
253 //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
254 //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
255 //sys   getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
256 //sys   recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
257 //sys   sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
258 //sys   Shutdown(s int, how int) (err error)
259
260 // In order to use msghdr structure with Control, Controllen in golang.org/x/net,
261 // nrecvmsg and nsendmsg must be used.
262 //sys   recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = nrecvmsg
263 //sys   sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg
264
265 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
266         if sa.Port < 0 || sa.Port > 0xFFFF {
267                 return nil, 0, EINVAL
268         }
269         sa.raw.Family = AF_INET
270         p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
271         p[0] = byte(sa.Port >> 8)
272         p[1] = byte(sa.Port)
273         sa.raw.Addr = sa.Addr
274         return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
275 }
276
277 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
278         if sa.Port < 0 || sa.Port > 0xFFFF {
279                 return nil, 0, EINVAL
280         }
281         sa.raw.Family = AF_INET6
282         p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
283         p[0] = byte(sa.Port >> 8)
284         p[1] = byte(sa.Port)
285         sa.raw.Scope_id = sa.ZoneId
286         sa.raw.Addr = sa.Addr
287         return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
288 }
289
290 func (sa *RawSockaddrUnix) setLen(n int) {
291         sa.Len = uint8(3 + n) // 2 for Family, Len; 1 for NUL.
292 }
293
294 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
295         name := sa.Name
296         n := len(name)
297         if n > len(sa.raw.Path) {
298                 return nil, 0, EINVAL
299         }
300         sa.raw.Family = AF_UNIX
301         sa.raw.setLen(n)
302         for i := 0; i < n; i++ {
303                 sa.raw.Path[i] = uint8(name[i])
304         }
305         // length is family (uint16), name, NUL.
306         sl := _Socklen(2)
307         if n > 0 {
308                 sl += _Socklen(n) + 1
309         }
310
311         return unsafe.Pointer(&sa.raw), sl, nil
312 }
313
314 func Getsockname(fd int) (sa Sockaddr, err error) {
315         var rsa RawSockaddrAny
316         var len _Socklen = SizeofSockaddrAny
317         if err = getsockname(fd, &rsa, &len); err != nil {
318                 return
319         }
320         return anyToSockaddr(&rsa)
321 }
322
323 //sys   accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
324
325 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
326         var rsa RawSockaddrAny
327         var len _Socklen = SizeofSockaddrAny
328         nfd, err = accept(fd, &rsa, &len)
329         if err != nil {
330                 return
331         }
332         sa, err = anyToSockaddr(&rsa)
333         if err != nil {
334                 Close(nfd)
335                 nfd = 0
336         }
337         return
338 }
339
340 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
341         var msg Msghdr
342         msg.Name = (*byte)(unsafe.Pointer(rsa))
343         msg.Namelen = uint32(SizeofSockaddrAny)
344         var iov Iovec
345         if len(p) > 0 {
346                 iov.Base = &p[0]
347                 iov.SetLen(len(p))
348         }
349         var dummy byte
350         if len(oob) > 0 {
351                 var sockType int
352                 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
353                 if err != nil {
354                         return
355                 }
356                 // receive at least one normal byte
357                 if sockType != SOCK_DGRAM && len(p) == 0 {
358                         iov.Base = &dummy
359                         iov.SetLen(1)
360                 }
361                 msg.Control = &oob[0]
362                 msg.SetControllen(len(oob))
363         }
364         msg.Iov = &iov
365         msg.Iovlen = 1
366         if n, err = recvmsg(fd, &msg, flags); err != nil {
367                 return
368         }
369         oobn = int(msg.Controllen)
370         recvflags = int(msg.Flags)
371         return
372 }
373
374 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
375         var msg Msghdr
376         msg.Name = (*byte)(ptr)
377         msg.Namelen = uint32(salen)
378         var iov Iovec
379         if len(p) > 0 {
380                 iov.Base = &p[0]
381                 iov.SetLen(len(p))
382         }
383         var dummy byte
384         if len(oob) > 0 {
385                 var sockType int
386                 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
387                 if err != nil {
388                         return 0, err
389                 }
390                 // send at least one normal byte
391                 if sockType != SOCK_DGRAM && len(p) == 0 {
392                         iov.Base = &dummy
393                         iov.SetLen(1)
394                 }
395                 msg.Control = &oob[0]
396                 msg.SetControllen(len(oob))
397         }
398         msg.Iov = &iov
399         msg.Iovlen = 1
400         if n, err = sendmsg(fd, &msg, flags); err != nil {
401                 return 0, err
402         }
403         if len(oob) > 0 && len(p) == 0 {
404                 n = 0
405         }
406         return n, nil
407 }
408
409 func (sa *RawSockaddrUnix) getLen() (int, error) {
410         // Some versions of AIX have a bug in getsockname (see IV78655).
411         // We can't rely on sa.Len being set correctly.
412         n := SizeofSockaddrUnix - 3 // subtract leading Family, Len, terminating NUL.
413         for i := 0; i < n; i++ {
414                 if sa.Path[i] == 0 {
415                         n = i
416                         break
417                 }
418         }
419         return n, nil
420 }
421
422 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
423         switch rsa.Addr.Family {
424         case AF_UNIX:
425                 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
426                 sa := new(SockaddrUnix)
427                 n, err := pp.getLen()
428                 if err != nil {
429                         return nil, err
430                 }
431                 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
432                 return sa, nil
433
434         case AF_INET:
435                 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
436                 sa := new(SockaddrInet4)
437                 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
438                 sa.Port = int(p[0])<<8 + int(p[1])
439                 sa.Addr = pp.Addr
440                 return sa, nil
441
442         case AF_INET6:
443                 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
444                 sa := new(SockaddrInet6)
445                 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
446                 sa.Port = int(p[0])<<8 + int(p[1])
447                 sa.Addr = pp.Addr
448                 return sa, nil
449         }
450         return nil, EAFNOSUPPORT
451 }
452
453 type SockaddrDatalink struct {
454         Len    uint8
455         Family uint8
456         Index  uint16
457         Type   uint8
458         Nlen   uint8
459         Alen   uint8
460         Slen   uint8
461         Data   [120]uint8
462         raw    RawSockaddrDatalink
463 }
464
465 /*
466  * Wait
467  */
468
469 type WaitStatus uint32
470
471 func (w WaitStatus) Stopped() bool { return w&0x40 != 0 }
472 func (w WaitStatus) StopSignal() Signal {
473         if !w.Stopped() {
474                 return -1
475         }
476         return Signal(w>>8) & 0xFF
477 }
478
479 func (w WaitStatus) Exited() bool { return w&0xFF == 0 }
480 func (w WaitStatus) ExitStatus() int {
481         if !w.Exited() {
482                 return -1
483         }
484         return int((w >> 8) & 0xFF)
485 }
486
487 func (w WaitStatus) Signaled() bool { return w&0x40 == 0 && w&0xFF != 0 }
488 func (w WaitStatus) Signal() Signal {
489         if !w.Signaled() {
490                 return -1
491         }
492         return Signal(w>>16) & 0xFF
493 }
494
495 func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 }
496
497 func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 }
498
499 func (w WaitStatus) TrapCause() int { return -1 }
500
501 /*
502  * ptrace
503  */
504
505 //sys   Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
506 //sys   ptrace64(request int, id int64, addr int64, data int, buff uintptr) (err error)
507 //sys   ptrace64Ptr(request int, id int64, addr int64, data int, buff unsafe.Pointer) (err error) = ptrace64
508
509 func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno {
510         if request == PTRACE_TRACEME {
511                 // Convert to AIX ptrace call.
512                 err := ptrace64(PT_TRACE_ME, 0, 0, 0, 0)
513                 if err != nil {
514                         return err.(Errno)
515                 }
516                 return 0
517         }
518         return ENOSYS
519 }
520
521 func ptracePeek(pid int, addr uintptr, out []byte) (count int, err error) {
522         n := 0
523         for len(out) > 0 {
524                 bsize := len(out)
525                 if bsize > 1024 {
526                         bsize = 1024
527                 }
528                 err = ptrace64Ptr(PT_READ_BLOCK, int64(pid), int64(addr), bsize, unsafe.Pointer(&out[0]))
529                 if err != nil {
530                         return 0, err
531                 }
532                 addr += uintptr(bsize)
533                 n += bsize
534                 out = out[n:]
535         }
536         return n, nil
537 }
538
539 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
540         return ptracePeek(pid, addr, out)
541 }
542
543 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
544         return ptracePeek(pid, addr, out)
545 }
546
547 func ptracePoke(pid int, addr uintptr, data []byte) (count int, err error) {
548         n := 0
549         for len(data) > 0 {
550                 bsize := len(data)
551                 if bsize > 1024 {
552                         bsize = 1024
553                 }
554                 err = ptrace64Ptr(PT_WRITE_BLOCK, int64(pid), int64(addr), bsize, unsafe.Pointer(&data[0]))
555                 if err != nil {
556                         return 0, err
557                 }
558                 addr += uintptr(bsize)
559                 n += bsize
560                 data = data[n:]
561         }
562         return n, nil
563 }
564
565 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
566         return ptracePoke(pid, addr, data)
567 }
568
569 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
570         return ptracePoke(pid, addr, data)
571 }
572
573 func PtraceCont(pid int, signal int) (err error) {
574         return ptrace64(PT_CONTINUE, int64(pid), 1, signal, 0)
575 }
576
577 func PtraceSingleStep(pid int) (err error) { return ptrace64(PT_STEP, int64(pid), 1, 0, 0) }
578
579 func PtraceAttach(pid int) (err error) { return ptrace64(PT_ATTACH, int64(pid), 0, 0, 0) }
580
581 func PtraceDetach(pid int) (err error) { return ptrace64(PT_DETACH, int64(pid), 0, 0, 0) }
582
583 /*
584  * Direct access
585  */
586
587 //sys   Acct(path string) (err error)
588 //sys   Chdir(path string) (err error)
589 //sys   Chmod(path string, mode uint32) (err error)
590 //sys   Chown(path string, uid int, gid int) (err error)
591 //sys   Chroot(path string) (err error)
592 //sys   Close(fd int) (err error)
593 //sys   Dup(fd int) (nfd int, err error)
594 //sys   Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
595 //sys   Fchdir(fd int) (err error)
596 //sys   Fchmod(fd int, mode uint32) (err error)
597 //sys   Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
598 //sys   Fchown(fd int, uid int, gid int) (err error)
599 //sys   Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
600 //sys   Fpathconf(fd int, name int) (val int, err error)
601 //sys   Fstat(fd int, stat *Stat_t) (err error)
602 //sys   Fstatfs(fd int, buf *Statfs_t) (err error)
603 //sys   Ftruncate(fd int, length int64) (err error)
604 //sysnb Getgid() (gid int)
605 //sysnb Getpid() (pid int)
606 //sys   Geteuid() (euid int)
607 //sys   Getegid() (egid int)
608 //sys   Getppid() (ppid int)
609 //sys   Getpriority(which int, who int) (n int, err error)
610 //sysnb Getrlimit(which int, lim *Rlimit) (err error)
611 //sysnb Getrusage(who int, rusage *Rusage) (err error)
612 //sysnb Getuid() (uid int)
613 //sys   Kill(pid int, signum Signal) (err error)
614 //sys   Lchown(path string, uid int, gid int) (err error)
615 //sys   Link(path string, link string) (err error)
616 //sys   Lstat(path string, stat *Stat_t) (err error)
617 //sys   Mkdir(path string, mode uint32) (err error)
618 //sys   Mkdirat(dirfd int, path string, mode uint32) (err error)
619 //sys   Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
620 //sys   Open(path string, mode int, perm uint32) (fd int, err error)
621 //sys   pread(fd int, p []byte, offset int64) (n int, err error)
622 //sys   pwrite(fd int, p []byte, offset int64) (n int, err error)
623 //sys   read(fd int, p []byte) (n int, err error)
624 //sys   Reboot(how int) (err error)
625 //sys   Rename(from string, to string) (err error)
626 //sys   Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
627 //sys   Rmdir(path string) (err error)
628 //sys   Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
629 //sysnb Setegid(egid int) (err error)
630 //sysnb Seteuid(euid int) (err error)
631 //sysnb Setgid(gid int) (err error)
632 //sysnb Setpgid(pid int, pgid int) (err error)
633 //sys   Setpriority(which int, who int, prio int) (err error)
634 //sysnb Setregid(rgid int, egid int) (err error)
635 //sysnb Setreuid(ruid int, euid int) (err error)
636 //sysnb setrlimit(which int, lim *Rlimit) (err error)
637 //sys   Stat(path string, stat *Stat_t) (err error)
638 //sys   Statfs(path string, buf *Statfs_t) (err error)
639 //sys   Symlink(path string, link string) (err error)
640 //sys   Truncate(path string, length int64) (err error)
641 //sys   Umask(newmask int) (oldmask int)
642 //sys   Unlink(path string) (err error)
643 //sysnb Uname(buf *Utsname) (err error)
644 //sys   write(fd int, p []byte) (n int, err error)
645 //sys   writev(fd int, iovecs []Iovec) (n uintptr, err error)
646
647 //sys   gettimeofday(tv *Timeval, tzp *Timezone) (err error)
648
649 func setTimespec(sec, nsec int64) Timespec {
650         return Timespec{Sec: sec, Nsec: nsec}
651 }
652
653 func setTimeval(sec, usec int64) Timeval {
654         return Timeval{Sec: sec, Usec: int32(usec)}
655 }
656
657 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
658         r0, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
659         n = int(r0)
660         if e1 != 0 {
661                 err = e1
662         }
663         return
664 }
665
666 /*
667  * Map
668  */
669
670 var mapper = &mmapper{
671         active: make(map[*byte][]byte),
672         mmap:   mmap,
673         munmap: munmap,
674 }
675
676 //sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
677 //sys   munmap(addr uintptr, length uintptr) (err error)
678
679 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
680         return mapper.Mmap(fd, offset, length, prot, flags)
681 }
682
683 func Munmap(b []byte) (err error) {
684         return mapper.Munmap(b)
685 }