github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/syscall/syscall_solaris.go (about)

     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 syscall
    14  
    15  import "unsafe"
    16  
    17  const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
    18  
    19  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    20  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    21  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    22  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    23  
    24  // Implemented in asm_solaris_amd64.s.
    25  func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    26  func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    27  
    28  type 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  
    39  func direntIno(buf []byte) (uint64, bool) {
    40  	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
    41  }
    42  
    43  func direntReclen(buf []byte) (uint64, bool) {
    44  	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
    45  }
    46  
    47  func 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  func Pipe(p []int) (err error) {
    56  	return Pipe2(p, 0)
    57  }
    58  
    59  //sysnb	pipe2(p *[2]_C_int, flags int) (err error)
    60  
    61  func Pipe2(p []int, flags int) error {
    62  	if len(p) != 2 {
    63  		return EINVAL
    64  	}
    65  	var pp [2]_C_int
    66  	err := pipe2(&pp, flags)
    67  	if err == nil {
    68  		p[0] = int(pp[0])
    69  		p[1] = int(pp[1])
    70  	}
    71  	return err
    72  }
    73  
    74  //sys   accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = libsocket.accept4
    75  
    76  func Accept4(fd int, flags int) (int, Sockaddr, error) {
    77  	var rsa RawSockaddrAny
    78  	var addrlen _Socklen = SizeofSockaddrAny
    79  	nfd, err := accept4(fd, &rsa, &addrlen, flags)
    80  	if err != nil {
    81  		return 0, nil, err
    82  	}
    83  	if addrlen > SizeofSockaddrAny {
    84  		panic("RawSockaddrAny too small")
    85  	}
    86  	sa, err := anyToSockaddr(&rsa)
    87  	if err != nil {
    88  		Close(nfd)
    89  		return 0, nil, err
    90  	}
    91  	return nfd, sa, nil
    92  }
    93  
    94  func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
    95  	if sa.Port < 0 || sa.Port > 0xFFFF {
    96  		return nil, 0, EINVAL
    97  	}
    98  	sa.raw.Family = AF_INET
    99  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
   100  	p[0] = byte(sa.Port >> 8)
   101  	p[1] = byte(sa.Port)
   102  	sa.raw.Addr = sa.Addr
   103  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
   104  }
   105  
   106  func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
   107  	if sa.Port < 0 || sa.Port > 0xFFFF {
   108  		return nil, 0, EINVAL
   109  	}
   110  	sa.raw.Family = AF_INET6
   111  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
   112  	p[0] = byte(sa.Port >> 8)
   113  	p[1] = byte(sa.Port)
   114  	sa.raw.Scope_id = sa.ZoneId
   115  	sa.raw.Addr = sa.Addr
   116  	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
   117  }
   118  
   119  func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
   120  	name := sa.Name
   121  	n := len(name)
   122  	if n >= len(sa.raw.Path) {
   123  		return nil, 0, EINVAL
   124  	}
   125  	sa.raw.Family = AF_UNIX
   126  	for i := 0; i < n; i++ {
   127  		sa.raw.Path[i] = int8(name[i])
   128  	}
   129  	// length is family (uint16), name, NUL.
   130  	sl := _Socklen(2)
   131  	if n > 0 {
   132  		sl += _Socklen(n) + 1
   133  	}
   134  	if sa.raw.Path[0] == '@' {
   135  		sa.raw.Path[0] = 0
   136  		// Don't count trailing NUL for abstract address.
   137  		sl--
   138  	}
   139  
   140  	return unsafe.Pointer(&sa.raw), sl, nil
   141  }
   142  
   143  func Getsockname(fd int) (sa Sockaddr, err error) {
   144  	var rsa RawSockaddrAny
   145  	var len _Socklen = SizeofSockaddrAny
   146  	if err = getsockname(fd, &rsa, &len); err != nil {
   147  		return
   148  	}
   149  	return anyToSockaddr(&rsa)
   150  }
   151  
   152  const ImplementsGetwd = true
   153  
   154  //sys	Getcwd(buf []byte) (n int, err error)
   155  
   156  func Getwd() (wd string, err error) {
   157  	var buf [PathMax]byte
   158  	// Getcwd will return an error if it failed for any reason.
   159  	_, err = Getcwd(buf[0:])
   160  	if err != nil {
   161  		return "", err
   162  	}
   163  	n := clen(buf[:])
   164  	if n < 1 {
   165  		return "", EINVAL
   166  	}
   167  	return string(buf[:n]), nil
   168  }
   169  
   170  /*
   171   * Wrapped
   172   */
   173  
   174  //sysnb	getgroups(ngid int, gid *_Gid_t) (n int, err error)
   175  //sysnb	setgroups(ngid int, gid *_Gid_t) (err error)
   176  
   177  func Getgroups() (gids []int, err error) {
   178  	n, err := getgroups(0, nil)
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  	if n == 0 {
   183  		return nil, nil
   184  	}
   185  
   186  	// Sanity check group count. Max is 16 on BSD.
   187  	if n < 0 || n > 1000 {
   188  		return nil, EINVAL
   189  	}
   190  
   191  	a := make([]_Gid_t, n)
   192  	n, err = getgroups(n, &a[0])
   193  	if err != nil {
   194  		return nil, err
   195  	}
   196  	gids = make([]int, n)
   197  	for i, v := range a[0:n] {
   198  		gids[i] = int(v)
   199  	}
   200  	return
   201  }
   202  
   203  func Setgroups(gids []int) (err error) {
   204  	if len(gids) == 0 {
   205  		return setgroups(0, nil)
   206  	}
   207  
   208  	a := make([]_Gid_t, len(gids))
   209  	for i, v := range gids {
   210  		a[i] = _Gid_t(v)
   211  	}
   212  	return setgroups(len(a), &a[0])
   213  }
   214  
   215  func ReadDirent(fd int, buf []byte) (n int, err error) {
   216  	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
   217  	// TODO(rsc): Can we use a single global basep for all calls?
   218  	return Getdents(fd, buf, new(uintptr))
   219  }
   220  
   221  // Wait status is 7 bits at bottom, either 0 (exited),
   222  // 0x7F (stopped), or a signal number that caused an exit.
   223  // The 0x80 bit is whether there was a core dump.
   224  // An extra number (exit code, signal causing a stop)
   225  // is in the high bits.
   226  
   227  type WaitStatus uint32
   228  
   229  const (
   230  	mask  = 0x7F
   231  	core  = 0x80
   232  	shift = 8
   233  
   234  	exited  = 0
   235  	stopped = 0x7F
   236  )
   237  
   238  func (w WaitStatus) Exited() bool { return w&mask == exited }
   239  
   240  func (w WaitStatus) ExitStatus() int {
   241  	if w&mask != exited {
   242  		return -1
   243  	}
   244  	return int(w >> shift)
   245  }
   246  
   247  func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
   248  
   249  func (w WaitStatus) Signal() Signal {
   250  	sig := Signal(w & mask)
   251  	if sig == stopped || sig == 0 {
   252  		return -1
   253  	}
   254  	return sig
   255  }
   256  
   257  func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
   258  
   259  func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
   260  
   261  func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
   262  
   263  func (w WaitStatus) StopSignal() Signal {
   264  	if !w.Stopped() {
   265  		return -1
   266  	}
   267  	return Signal(w>>shift) & 0xFF
   268  }
   269  
   270  func (w WaitStatus) TrapCause() int { return -1 }
   271  
   272  func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
   273  
   274  func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
   275  	r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
   276  	if e1 != 0 {
   277  		err = Errno(e1)
   278  	}
   279  	return int(r0), err
   280  }
   281  
   282  func gethostname() (name string, err uintptr)
   283  
   284  func Gethostname() (name string, err error) {
   285  	name, e1 := gethostname()
   286  	if e1 != 0 {
   287  		err = Errno(e1)
   288  	}
   289  	return name, err
   290  }
   291  
   292  func UtimesNano(path string, ts []Timespec) error {
   293  	if len(ts) != 2 {
   294  		return EINVAL
   295  	}
   296  	return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
   297  }
   298  
   299  //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
   300  
   301  // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
   302  func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
   303  	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
   304  	if e1 != 0 {
   305  		return e1
   306  	}
   307  	return nil
   308  }
   309  
   310  func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
   311  	switch rsa.Addr.Family {
   312  	case AF_UNIX:
   313  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
   314  		sa := new(SockaddrUnix)
   315  		// Assume path ends at NUL.
   316  		// This is not technically the Solaris semantics for
   317  		// abstract Unix domain sockets -- they are supposed
   318  		// to be uninterpreted fixed-size binary blobs -- but
   319  		// everyone uses this convention.
   320  		n := 0
   321  		for n < len(pp.Path) && pp.Path[n] != 0 {
   322  			n++
   323  		}
   324  		sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
   325  		return sa, nil
   326  
   327  	case AF_INET:
   328  		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
   329  		sa := new(SockaddrInet4)
   330  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   331  		sa.Port = int(p[0])<<8 + int(p[1])
   332  		sa.Addr = pp.Addr
   333  		return sa, nil
   334  
   335  	case AF_INET6:
   336  		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
   337  		sa := new(SockaddrInet6)
   338  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   339  		sa.Port = int(p[0])<<8 + int(p[1])
   340  		sa.ZoneId = pp.Scope_id
   341  		sa.Addr = pp.Addr
   342  		return sa, nil
   343  	}
   344  	return nil, EAFNOSUPPORT
   345  }
   346  
   347  //sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libsocket.accept
   348  
   349  func Accept(fd int) (nfd int, sa Sockaddr, err error) {
   350  	var rsa RawSockaddrAny
   351  	var len _Socklen = SizeofSockaddrAny
   352  	nfd, err = accept(fd, &rsa, &len)
   353  	if err != nil {
   354  		return
   355  	}
   356  	sa, err = anyToSockaddr(&rsa)
   357  	if err != nil {
   358  		Close(nfd)
   359  		nfd = 0
   360  	}
   361  	return
   362  }
   363  
   364  func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
   365  	var msg Msghdr
   366  	msg.Name = (*byte)(unsafe.Pointer(rsa))
   367  	msg.Namelen = uint32(SizeofSockaddrAny)
   368  	var iov Iovec
   369  	if len(p) > 0 {
   370  		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
   371  		iov.SetLen(len(p))
   372  	}
   373  	var dummy int8
   374  	if len(oob) > 0 {
   375  		// receive at least one normal byte
   376  		if len(p) == 0 {
   377  			iov.Base = &dummy
   378  			iov.SetLen(1)
   379  		}
   380  		msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
   381  		msg.Accrightslen = int32(len(oob))
   382  	}
   383  	msg.Iov = &iov
   384  	msg.Iovlen = 1
   385  	if n, err = recvmsg(fd, &msg, flags); err != nil {
   386  		return
   387  	}
   388  	oobn = int(msg.Accrightslen)
   389  	return
   390  }
   391  
   392  //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg
   393  
   394  func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
   395  	var msg Msghdr
   396  	msg.Name = (*byte)(unsafe.Pointer(ptr))
   397  	msg.Namelen = uint32(salen)
   398  	var iov Iovec
   399  	if len(p) > 0 {
   400  		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
   401  		iov.SetLen(len(p))
   402  	}
   403  	var dummy int8
   404  	if len(oob) > 0 {
   405  		// send at least one normal byte
   406  		if len(p) == 0 {
   407  			iov.Base = &dummy
   408  			iov.SetLen(1)
   409  		}
   410  		msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
   411  		msg.Accrightslen = int32(len(oob))
   412  	}
   413  	msg.Iov = &iov
   414  	msg.Iovlen = 1
   415  	if n, err = sendmsg(fd, &msg, flags); err != nil {
   416  		return 0, err
   417  	}
   418  	if len(oob) > 0 && len(p) == 0 {
   419  		n = 0
   420  	}
   421  	return n, nil
   422  }
   423  
   424  /*
   425   * Exposed directly
   426   */
   427  //sys	Access(path string, mode uint32) (err error)
   428  //sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
   429  //sys	Chdir(path string) (err error)
   430  //sys	Chmod(path string, mode uint32) (err error)
   431  //sys	Chown(path string, uid int, gid int) (err error)
   432  //sys	Chroot(path string) (err error)
   433  //sys	Close(fd int) (err error)
   434  //sys	Dup(fd int) (nfd int, err error)
   435  //sys	Fchdir(fd int) (err error)
   436  //sys	Fchmod(fd int, mode uint32) (err error)
   437  //sys	Fchown(fd int, uid int, gid int) (err error)
   438  //sys	Fpathconf(fd int, name int) (val int, err error)
   439  //sys	Fstat(fd int, stat *Stat_t) (err error)
   440  //sys	Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
   441  //sysnb	Getgid() (gid int)
   442  //sysnb	Getpid() (pid int)
   443  //sys	Geteuid() (euid int)
   444  //sys	Getegid() (egid int)
   445  //sys	Getppid() (ppid int)
   446  //sys	Getpriority(which int, who int) (n int, err error)
   447  //sysnb	Getrlimit(which int, lim *Rlimit) (err error)
   448  //sysnb	Getrusage(who int, rusage *Rusage) (err error)
   449  //sysnb	Gettimeofday(tv *Timeval) (err error)
   450  //sysnb	Getuid() (uid int)
   451  //sys	Kill(pid int, signum Signal) (err error)
   452  //sys	Lchown(path string, uid int, gid int) (err error)
   453  //sys	Link(path string, link string) (err error)
   454  //sys	Listen(s int, backlog int) (err error) = libsocket.__xnet_listen
   455  //sys	Lstat(path string, stat *Stat_t) (err error)
   456  //sys	Mkdir(path string, mode uint32) (err error)
   457  //sys	Mknod(path string, mode uint32, dev int) (err error)
   458  //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
   459  //sys	Open(path string, mode int, perm uint32) (fd int, err error)
   460  //sys	Pathconf(path string, name int) (val int, err error)
   461  //sys	pread(fd int, p []byte, offset int64) (n int, err error)
   462  //sys	pwrite(fd int, p []byte, offset int64) (n int, err error)
   463  //sys	read(fd int, p []byte) (n int, err error)
   464  //sys	Readlink(path string, buf []byte) (n int, err error)
   465  //sys	Rename(from string, to string) (err error)
   466  //sys	Rmdir(path string) (err error)
   467  //sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
   468  //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile
   469  //sysnb	Setegid(egid int) (err error)
   470  //sysnb	Seteuid(euid int) (err error)
   471  //sysnb	Setgid(gid int) (err error)
   472  //sysnb	Setpgid(pid int, pgid int) (err error)
   473  //sys	Setpriority(which int, who int, prio int) (err error)
   474  //sysnb	Setregid(rgid int, egid int) (err error)
   475  //sysnb	Setreuid(ruid int, euid int) (err error)
   476  //sysnb	setrlimit(which int, lim *Rlimit) (err error)
   477  //sysnb	Setsid() (pid int, err error)
   478  //sysnb	Setuid(uid int) (err error)
   479  //sys	Shutdown(s int, how int) (err error) = libsocket.shutdown
   480  //sys	Stat(path string, stat *Stat_t) (err error)
   481  //sys	Symlink(path string, link string) (err error)
   482  //sys	Sync() (err error)
   483  //sys	Truncate(path string, length int64) (err error)
   484  //sys	Fsync(fd int) (err error)
   485  //sys	Ftruncate(fd int, length int64) (err error)
   486  //sys	Umask(newmask int) (oldmask int)
   487  //sys	Unlink(path string) (err error)
   488  //sys	utimes(path string, times *[2]Timeval) (err error)
   489  //sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_bind
   490  //sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect
   491  //sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
   492  //sys	munmap(addr uintptr, length uintptr) (err error)
   493  //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto
   494  //sys	socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket
   495  //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair
   496  //sys	write(fd int, p []byte) (n int, err error)
   497  //sys	writev(fd int, iovecs []Iovec) (n uintptr, err error)
   498  //sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.__xnet_getsockopt
   499  //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername
   500  //sys	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname
   501  //sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt
   502  //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom
   503  //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg
   504  //sys	getexecname() (path unsafe.Pointer, err error) = libc.getexecname
   505  //sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
   506  
   507  func Getexecname() (path string, err error) {
   508  	ptr, err := getexecname()
   509  	if err != nil {
   510  		return "", err
   511  	}
   512  	bytes := (*[1 << 29]byte)(ptr)[:]
   513  	for i, b := range bytes {
   514  		if b == 0 {
   515  			return string(bytes[:i]), nil
   516  		}
   517  	}
   518  	panic("unreachable")
   519  }
   520  
   521  func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
   522  	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
   523  	n = int(r0)
   524  	if e1 != 0 {
   525  		err = e1
   526  	}
   527  	return
   528  }
   529  
   530  func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
   531  	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_write)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
   532  	n = int(r0)
   533  	if e1 != 0 {
   534  		err = e1
   535  	}
   536  	return
   537  }
   538  
   539  var mapper = &mmapper{
   540  	active: make(map[*byte][]byte),
   541  	mmap:   mmap,
   542  	munmap: munmap,
   543  }
   544  
   545  func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
   546  	return mapper.Mmap(fd, offset, length, prot, flags)
   547  }
   548  
   549  func Munmap(b []byte) (err error) {
   550  	return mapper.Munmap(b)
   551  }
   552  
   553  func Utimes(path string, tv []Timeval) error {
   554  	if len(tv) != 2 {
   555  		return EINVAL
   556  	}
   557  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   558  }