github.com/HACKERALERT/Picocrypt/src/external/sys@v0.0.0-20210609020157-e519952f829f/unix/syscall_zos_s390x.go (about)

     1  // Copyright 2020 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  //go:build zos && s390x
     6  // +build zos,s390x
     7  
     8  package unix
     9  
    10  import (
    11  	"bytes"
    12  	"runtime"
    13  	"sort"
    14  	"sync"
    15  	"syscall"
    16  	"unsafe"
    17  )
    18  
    19  const (
    20  	O_CLOEXEC = 0       // Dummy value (not supported).
    21  	AF_LOCAL  = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
    22  )
    23  
    24  func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    25  func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    26  func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    27  func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    28  func syscall_syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
    29  func syscall_rawsyscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
    30  
    31  func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
    32  	stat.Dev = uint64(statLE.Dev)
    33  	stat.Ino = uint64(statLE.Ino)
    34  	stat.Nlink = uint64(statLE.Nlink)
    35  	stat.Mode = uint32(statLE.Mode)
    36  	stat.Uid = uint32(statLE.Uid)
    37  	stat.Gid = uint32(statLE.Gid)
    38  	stat.Rdev = uint64(statLE.Rdev)
    39  	stat.Size = statLE.Size
    40  	stat.Atim.Sec = int64(statLE.Atim)
    41  	stat.Atim.Nsec = 0 //zos doesn't return nanoseconds
    42  	stat.Mtim.Sec = int64(statLE.Mtim)
    43  	stat.Mtim.Nsec = 0 //zos doesn't return nanoseconds
    44  	stat.Ctim.Sec = int64(statLE.Ctim)
    45  	stat.Ctim.Nsec = 0 //zos doesn't return nanoseconds
    46  	stat.Blksize = int64(statLE.Blksize)
    47  	stat.Blocks = statLE.Blocks
    48  }
    49  
    50  func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
    51  func svcLoad(name *byte) unsafe.Pointer
    52  func svcUnload(name *byte, fnptr unsafe.Pointer) int64
    53  
    54  func (d *Dirent) NameString() string {
    55  	if d == nil {
    56  		return ""
    57  	}
    58  	return string(d.Name[:d.Namlen])
    59  }
    60  
    61  func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
    62  	if sa.Port < 0 || sa.Port > 0xFFFF {
    63  		return nil, 0, EINVAL
    64  	}
    65  	sa.raw.Len = SizeofSockaddrInet4
    66  	sa.raw.Family = AF_INET
    67  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
    68  	p[0] = byte(sa.Port >> 8)
    69  	p[1] = byte(sa.Port)
    70  	for i := 0; i < len(sa.Addr); i++ {
    71  		sa.raw.Addr[i] = sa.Addr[i]
    72  	}
    73  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
    74  }
    75  
    76  func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
    77  	if sa.Port < 0 || sa.Port > 0xFFFF {
    78  		return nil, 0, EINVAL
    79  	}
    80  	sa.raw.Len = SizeofSockaddrInet6
    81  	sa.raw.Family = AF_INET6
    82  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
    83  	p[0] = byte(sa.Port >> 8)
    84  	p[1] = byte(sa.Port)
    85  	sa.raw.Scope_id = sa.ZoneId
    86  	for i := 0; i < len(sa.Addr); i++ {
    87  		sa.raw.Addr[i] = sa.Addr[i]
    88  	}
    89  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
    90  }
    91  
    92  func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
    93  	name := sa.Name
    94  	n := len(name)
    95  	if n >= len(sa.raw.Path) || n == 0 {
    96  		return nil, 0, EINVAL
    97  	}
    98  	sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
    99  	sa.raw.Family = AF_UNIX
   100  	for i := 0; i < n; i++ {
   101  		sa.raw.Path[i] = int8(name[i])
   102  	}
   103  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
   104  }
   105  
   106  func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
   107  	// TODO(neeilan): Implement use of first param (fd)
   108  	switch rsa.Addr.Family {
   109  	case AF_UNIX:
   110  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
   111  		sa := new(SockaddrUnix)
   112  		// For z/OS, only replace NUL with @ when the
   113  		// length is not zero.
   114  		if pp.Len != 0 && pp.Path[0] == 0 {
   115  			// "Abstract" Unix domain socket.
   116  			// Rewrite leading NUL as @ for textual display.
   117  			// (This is the standard convention.)
   118  			// Not friendly to overwrite in place,
   119  			// but the callers below don't care.
   120  			pp.Path[0] = '@'
   121  		}
   122  
   123  		// Assume path ends at NUL.
   124  		//
   125  		// For z/OS, the length of the name is a field
   126  		// in the structure. To be on the safe side, we
   127  		// will still scan the name for a NUL but only
   128  		// to the length provided in the structure.
   129  		//
   130  		// This is not technically the Linux semantics for
   131  		// abstract Unix domain sockets--they are supposed
   132  		// to be uninterpreted fixed-size binary blobs--but
   133  		// everyone uses this convention.
   134  		n := 0
   135  		for n < int(pp.Len) && pp.Path[n] != 0 {
   136  			n++
   137  		}
   138  		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
   139  		sa.Name = string(bytes)
   140  		return sa, nil
   141  
   142  	case AF_INET:
   143  		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
   144  		sa := new(SockaddrInet4)
   145  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   146  		sa.Port = int(p[0])<<8 + int(p[1])
   147  		for i := 0; i < len(sa.Addr); i++ {
   148  			sa.Addr[i] = pp.Addr[i]
   149  		}
   150  		return sa, nil
   151  
   152  	case AF_INET6:
   153  		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
   154  		sa := new(SockaddrInet6)
   155  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   156  		sa.Port = int(p[0])<<8 + int(p[1])
   157  		sa.ZoneId = pp.Scope_id
   158  		for i := 0; i < len(sa.Addr); i++ {
   159  			sa.Addr[i] = pp.Addr[i]
   160  		}
   161  		return sa, nil
   162  	}
   163  	return nil, EAFNOSUPPORT
   164  }
   165  
   166  func Accept(fd int) (nfd int, sa Sockaddr, err error) {
   167  	var rsa RawSockaddrAny
   168  	var len _Socklen = SizeofSockaddrAny
   169  	nfd, err = accept(fd, &rsa, &len)
   170  	if err != nil {
   171  		return
   172  	}
   173  	// TODO(neeilan): Remove 0 in call
   174  	sa, err = anyToSockaddr(0, &rsa)
   175  	if err != nil {
   176  		Close(nfd)
   177  		nfd = 0
   178  	}
   179  	return
   180  }
   181  
   182  func (iov *Iovec) SetLen(length int) {
   183  	iov.Len = uint64(length)
   184  }
   185  
   186  func (msghdr *Msghdr) SetControllen(length int) {
   187  	msghdr.Controllen = int32(length)
   188  }
   189  
   190  func (cmsg *Cmsghdr) SetLen(length int) {
   191  	cmsg.Len = int32(length)
   192  }
   193  
   194  //sys   fcntl(fd int, cmd int, arg int) (val int, err error)
   195  //sys	read(fd int, p []byte) (n int, err error)
   196  //sys   readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
   197  //sys	write(fd int, p []byte) (n int, err error)
   198  
   199  //sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A
   200  //sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A
   201  //sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A
   202  //sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
   203  //sysnb	setgroups(n int, list *_Gid_t) (err error)
   204  //sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
   205  //sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
   206  //sysnb	socket(domain int, typ int, proto int) (fd int, err error)
   207  //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
   208  //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A
   209  //sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A
   210  //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A
   211  //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A
   212  //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A
   213  //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A
   214  //sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP
   215  //sys   munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP
   216  //sys   ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL
   217  
   218  //sys   Access(path string, mode uint32) (err error) = SYS___ACCESS_A
   219  //sys   Chdir(path string) (err error) = SYS___CHDIR_A
   220  //sys	Chown(path string, uid int, gid int) (err error) = SYS___CHOWN_A
   221  //sys	Chmod(path string, mode uint32) (err error) = SYS___CHMOD_A
   222  //sys   Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A
   223  //sys	Dup(oldfd int) (fd int, err error)
   224  //sys	Dup2(oldfd int, newfd int) (err error)
   225  //sys	Errno2() (er2 int) = SYS___ERRNO2
   226  //sys	Err2ad() (eadd *int) = SYS___ERR2AD
   227  //sys	Exit(code int)
   228  //sys	Fchdir(fd int) (err error)
   229  //sys	Fchmod(fd int, mode uint32) (err error)
   230  //sys	Fchown(fd int, uid int, gid int) (err error)
   231  //sys	FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) = SYS_FCNTL
   232  //sys	fstat(fd int, stat *Stat_LE_t) (err error)
   233  
   234  func Fstat(fd int, stat *Stat_t) (err error) {
   235  	var statLE Stat_LE_t
   236  	err = fstat(fd, &statLE)
   237  	copyStat(stat, &statLE)
   238  	return
   239  }
   240  
   241  //sys	Fstatvfs(fd int, stat *Statvfs_t) (err error) = SYS_FSTATVFS
   242  //sys	Fsync(fd int) (err error)
   243  //sys	Ftruncate(fd int, length int64) (err error)
   244  //sys   Getpagesize() (pgsize int) = SYS_GETPAGESIZE
   245  //sys   Mprotect(b []byte, prot int) (err error) = SYS_MPROTECT
   246  //sys   Msync(b []byte, flags int) (err error) = SYS_MSYNC
   247  //sys   Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL
   248  //sys   Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES
   249  //sys   W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT
   250  //sys   W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A
   251  
   252  //sys   mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
   253  //sys   unmount(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
   254  //sys   Chroot(path string) (err error) = SYS___CHROOT_A
   255  //sys   Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT
   256  //sysnb Uname(buf *Utsname) (err error) = SYS___UNAME_A
   257  
   258  func Ptsname(fd int) (name string, err error) {
   259  	r0, _, e1 := syscall_syscall(SYS___PTSNAME_A, uintptr(fd), 0, 0)
   260  	name = u2s(unsafe.Pointer(r0))
   261  	if e1 != 0 {
   262  		err = errnoErr(e1)
   263  	}
   264  	return
   265  }
   266  
   267  func u2s(cstr unsafe.Pointer) string {
   268  	str := (*[1024]uint8)(cstr)
   269  	i := 0
   270  	for str[i] != 0 {
   271  		i++
   272  	}
   273  	return string(str[:i])
   274  }
   275  
   276  func Close(fd int) (err error) {
   277  	_, _, e1 := syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
   278  	for i := 0; e1 == EAGAIN && i < 10; i++ {
   279  		_, _, _ = syscall_syscall(SYS_USLEEP, uintptr(10), 0, 0)
   280  		_, _, e1 = syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
   281  	}
   282  	if e1 != 0 {
   283  		err = errnoErr(e1)
   284  	}
   285  	return
   286  }
   287  
   288  var mapper = &mmapper{
   289  	active: make(map[*byte][]byte),
   290  	mmap:   mmap,
   291  	munmap: munmap,
   292  }
   293  
   294  // Dummy function: there are no semantics for Madvise on z/OS
   295  func Madvise(b []byte, advice int) (err error) {
   296  	return
   297  }
   298  
   299  func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
   300  	return mapper.Mmap(fd, offset, length, prot, flags)
   301  }
   302  
   303  func Munmap(b []byte) (err error) {
   304  	return mapper.Munmap(b)
   305  }
   306  
   307  //sys   Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
   308  //sysnb	Getegid() (egid int)
   309  //sysnb	Geteuid() (uid int)
   310  //sysnb	Getgid() (gid int)
   311  //sysnb	Getpid() (pid int)
   312  //sysnb	Getpgid(pid int) (pgid int, err error) = SYS_GETPGID
   313  
   314  func Getpgrp() (pid int) {
   315  	pid, _ = Getpgid(0)
   316  	return
   317  }
   318  
   319  //sysnb	Getppid() (pid int)
   320  //sys	Getpriority(which int, who int) (prio int, err error)
   321  //sysnb	Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT
   322  
   323  //sysnb getrusage(who int, rusage *rusage_zos) (err error) = SYS_GETRUSAGE
   324  
   325  func Getrusage(who int, rusage *Rusage) (err error) {
   326  	var ruz rusage_zos
   327  	err = getrusage(who, &ruz)
   328  	//Only the first two fields of Rusage are set
   329  	rusage.Utime.Sec = ruz.Utime.Sec
   330  	rusage.Utime.Usec = int64(ruz.Utime.Usec)
   331  	rusage.Stime.Sec = ruz.Stime.Sec
   332  	rusage.Stime.Usec = int64(ruz.Stime.Usec)
   333  	return
   334  }
   335  
   336  //sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID
   337  //sysnb	Getuid() (uid int)
   338  //sysnb	Kill(pid int, sig Signal) (err error)
   339  //sys	Lchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A
   340  //sys	Link(path string, link string) (err error) = SYS___LINK_A
   341  //sys	Listen(s int, n int) (err error)
   342  //sys	lstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A
   343  
   344  func Lstat(path string, stat *Stat_t) (err error) {
   345  	var statLE Stat_LE_t
   346  	err = lstat(path, &statLE)
   347  	copyStat(stat, &statLE)
   348  	return
   349  }
   350  
   351  //sys	Mkdir(path string, mode uint32) (err error) = SYS___MKDIR_A
   352  //sys   Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A
   353  //sys	Mknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A
   354  //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
   355  //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
   356  //sys	Readlink(path string, buf []byte) (n int, err error) = SYS___READLINK_A
   357  //sys	Rename(from string, to string) (err error) = SYS___RENAME_A
   358  //sys	Rmdir(path string) (err error) = SYS___RMDIR_A
   359  //sys   Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
   360  //sys	Setpriority(which int, who int, prio int) (err error)
   361  //sysnb	Setpgid(pid int, pgid int) (err error) = SYS_SETPGID
   362  //sysnb	Setrlimit(resource int, lim *Rlimit) (err error)
   363  //sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID
   364  //sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID
   365  //sysnb	Setsid() (pid int, err error) = SYS_SETSID
   366  //sys	Setuid(uid int) (err error) = SYS_SETUID
   367  //sys	Setgid(uid int) (err error) = SYS_SETGID
   368  //sys	Shutdown(fd int, how int) (err error)
   369  //sys	stat(path string, statLE *Stat_LE_t) (err error) = SYS___STAT_A
   370  
   371  func Stat(path string, sta *Stat_t) (err error) {
   372  	var statLE Stat_LE_t
   373  	err = stat(path, &statLE)
   374  	copyStat(sta, &statLE)
   375  	return
   376  }
   377  
   378  //sys	Symlink(path string, link string) (err error) = SYS___SYMLINK_A
   379  //sys	Sync() = SYS_SYNC
   380  //sys	Truncate(path string, length int64) (err error) = SYS___TRUNCATE_A
   381  //sys	Tcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR
   382  //sys	Tcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR
   383  //sys	Umask(mask int) (oldmask int)
   384  //sys	Unlink(path string) (err error) = SYS___UNLINK_A
   385  //sys	Utime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A
   386  
   387  //sys	open(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A
   388  
   389  func Open(path string, mode int, perm uint32) (fd int, err error) {
   390  	return open(path, mode, perm)
   391  }
   392  
   393  func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
   394  	wd, err := Getwd()
   395  	if err != nil {
   396  		return err
   397  	}
   398  
   399  	if err := Fchdir(dirfd); err != nil {
   400  		return err
   401  	}
   402  	defer Chdir(wd)
   403  
   404  	return Mkfifo(path, mode)
   405  }
   406  
   407  //sys	remove(path string) (err error)
   408  
   409  func Remove(path string) error {
   410  	return remove(path)
   411  }
   412  
   413  const ImplementsGetwd = true
   414  
   415  func Getcwd(buf []byte) (n int, err error) {
   416  	var p unsafe.Pointer
   417  	if len(buf) > 0 {
   418  		p = unsafe.Pointer(&buf[0])
   419  	} else {
   420  		p = unsafe.Pointer(&_zero)
   421  	}
   422  	_, _, e := syscall_syscall(SYS___GETCWD_A, uintptr(p), uintptr(len(buf)), 0)
   423  	n = clen(buf) + 1
   424  	if e != 0 {
   425  		err = errnoErr(e)
   426  	}
   427  	return
   428  }
   429  
   430  func Getwd() (wd string, err error) {
   431  	var buf [PathMax]byte
   432  	n, err := Getcwd(buf[0:])
   433  	if err != nil {
   434  		return "", err
   435  	}
   436  	// Getcwd returns the number of bytes written to buf, including the NUL.
   437  	if n < 1 || n > len(buf) || buf[n-1] != 0 {
   438  		return "", EINVAL
   439  	}
   440  	return string(buf[0 : n-1]), nil
   441  }
   442  
   443  func Getgroups() (gids []int, err error) {
   444  	n, err := getgroups(0, nil)
   445  	if err != nil {
   446  		return nil, err
   447  	}
   448  	if n == 0 {
   449  		return nil, nil
   450  	}
   451  
   452  	// Sanity check group count.  Max is 1<<16 on Linux.
   453  	if n < 0 || n > 1<<20 {
   454  		return nil, EINVAL
   455  	}
   456  
   457  	a := make([]_Gid_t, n)
   458  	n, err = getgroups(n, &a[0])
   459  	if err != nil {
   460  		return nil, err
   461  	}
   462  	gids = make([]int, n)
   463  	for i, v := range a[0:n] {
   464  		gids[i] = int(v)
   465  	}
   466  	return
   467  }
   468  
   469  func Setgroups(gids []int) (err error) {
   470  	if len(gids) == 0 {
   471  		return setgroups(0, nil)
   472  	}
   473  
   474  	a := make([]_Gid_t, len(gids))
   475  	for i, v := range gids {
   476  		a[i] = _Gid_t(v)
   477  	}
   478  	return setgroups(len(a), &a[0])
   479  }
   480  
   481  func gettid() uint64
   482  
   483  func Gettid() (tid int) {
   484  	return int(gettid())
   485  }
   486  
   487  type WaitStatus uint32
   488  
   489  // Wait status is 7 bits at bottom, either 0 (exited),
   490  // 0x7F (stopped), or a signal number that caused an exit.
   491  // The 0x80 bit is whether there was a core dump.
   492  // An extra number (exit code, signal causing a stop)
   493  // is in the high bits.  At least that's the idea.
   494  // There are various irregularities.  For example, the
   495  // "continued" status is 0xFFFF, distinguishing itself
   496  // from stopped via the core dump bit.
   497  
   498  const (
   499  	mask    = 0x7F
   500  	core    = 0x80
   501  	exited  = 0x00
   502  	stopped = 0x7F
   503  	shift   = 8
   504  )
   505  
   506  func (w WaitStatus) Exited() bool { return w&mask == exited }
   507  
   508  func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
   509  
   510  func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
   511  
   512  func (w WaitStatus) Continued() bool { return w == 0xFFFF }
   513  
   514  func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
   515  
   516  func (w WaitStatus) ExitStatus() int {
   517  	if !w.Exited() {
   518  		return -1
   519  	}
   520  	return int(w>>shift) & 0xFF
   521  }
   522  
   523  func (w WaitStatus) Signal() Signal {
   524  	if !w.Signaled() {
   525  		return -1
   526  	}
   527  	return Signal(w & mask)
   528  }
   529  
   530  func (w WaitStatus) StopSignal() Signal {
   531  	if !w.Stopped() {
   532  		return -1
   533  	}
   534  	return Signal(w>>shift) & 0xFF
   535  }
   536  
   537  func (w WaitStatus) TrapCause() int { return -1 }
   538  
   539  //sys	waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)
   540  
   541  func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
   542  	// TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.
   543  	// At the moment rusage will not be touched.
   544  	var status _C_int
   545  	wpid, err = waitpid(pid, &status, options)
   546  	if wstatus != nil {
   547  		*wstatus = WaitStatus(status)
   548  	}
   549  	return
   550  }
   551  
   552  //sysnb	gettimeofday(tv *timeval_zos) (err error)
   553  
   554  func Gettimeofday(tv *Timeval) (err error) {
   555  	var tvz timeval_zos
   556  	err = gettimeofday(&tvz)
   557  	tv.Sec = tvz.Sec
   558  	tv.Usec = int64(tvz.Usec)
   559  	return
   560  }
   561  
   562  func Time(t *Time_t) (tt Time_t, err error) {
   563  	var tv Timeval
   564  	err = Gettimeofday(&tv)
   565  	if err != nil {
   566  		return 0, err
   567  	}
   568  	if t != nil {
   569  		*t = Time_t(tv.Sec)
   570  	}
   571  	return Time_t(tv.Sec), nil
   572  }
   573  
   574  func setTimespec(sec, nsec int64) Timespec {
   575  	return Timespec{Sec: sec, Nsec: nsec}
   576  }
   577  
   578  func setTimeval(sec, usec int64) Timeval { //fix
   579  	return Timeval{Sec: sec, Usec: usec}
   580  }
   581  
   582  //sysnb pipe(p *[2]_C_int) (err error)
   583  
   584  func Pipe(p []int) (err error) {
   585  	if len(p) != 2 {
   586  		return EINVAL
   587  	}
   588  	var pp [2]_C_int
   589  	err = pipe(&pp)
   590  	p[0] = int(pp[0])
   591  	p[1] = int(pp[1])
   592  	return
   593  }
   594  
   595  //sys	utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
   596  
   597  func Utimes(path string, tv []Timeval) (err error) {
   598  	if len(tv) != 2 {
   599  		return EINVAL
   600  	}
   601  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   602  }
   603  
   604  func UtimesNano(path string, ts []Timespec) error {
   605  	if len(ts) != 2 {
   606  		return EINVAL
   607  	}
   608  	// Not as efficient as it could be because Timespec and
   609  	// Timeval have different types in the different OSes
   610  	tv := [2]Timeval{
   611  		NsecToTimeval(TimespecToNsec(ts[0])),
   612  		NsecToTimeval(TimespecToNsec(ts[1])),
   613  	}
   614  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   615  }
   616  
   617  func Getsockname(fd int) (sa Sockaddr, err error) {
   618  	var rsa RawSockaddrAny
   619  	var len _Socklen = SizeofSockaddrAny
   620  	if err = getsockname(fd, &rsa, &len); err != nil {
   621  		return
   622  	}
   623  	// TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )
   624  	return anyToSockaddr(0, &rsa)
   625  }
   626  
   627  const (
   628  	// identifier constants
   629  	nwmHeaderIdentifier    = 0xd5e6d4c8
   630  	nwmFilterIdentifier    = 0xd5e6d4c6
   631  	nwmTCPConnIdentifier   = 0xd5e6d4c3
   632  	nwmRecHeaderIdentifier = 0xd5e6d4d9
   633  	nwmIPStatsIdentifier   = 0xd5e6d4c9d7e2e340
   634  	nwmIPGStatsIdentifier  = 0xd5e6d4c9d7c7e2e3
   635  	nwmTCPStatsIdentifier  = 0xd5e6d4e3c3d7e2e3
   636  	nwmUDPStatsIdentifier  = 0xd5e6d4e4c4d7e2e3
   637  	nwmICMPGStatsEntry     = 0xd5e6d4c9c3d4d7c7
   638  	nwmICMPTStatsEntry     = 0xd5e6d4c9c3d4d7e3
   639  
   640  	// nwmHeader constants
   641  	nwmVersion1   = 1
   642  	nwmVersion2   = 2
   643  	nwmCurrentVer = 2
   644  
   645  	nwmTCPConnType     = 1
   646  	nwmGlobalStatsType = 14
   647  
   648  	// nwmFilter constants
   649  	nwmFilterLclAddrMask = 0x20000000 // Local address
   650  	nwmFilterSrcAddrMask = 0x20000000 // Source address
   651  	nwmFilterLclPortMask = 0x10000000 // Local port
   652  	nwmFilterSrcPortMask = 0x10000000 // Source port
   653  
   654  	// nwmConnEntry constants
   655  	nwmTCPStateClosed   = 1
   656  	nwmTCPStateListen   = 2
   657  	nwmTCPStateSynSent  = 3
   658  	nwmTCPStateSynRcvd  = 4
   659  	nwmTCPStateEstab    = 5
   660  	nwmTCPStateFinWait1 = 6
   661  	nwmTCPStateFinWait2 = 7
   662  	nwmTCPStateClosWait = 8
   663  	nwmTCPStateLastAck  = 9
   664  	nwmTCPStateClosing  = 10
   665  	nwmTCPStateTimeWait = 11
   666  	nwmTCPStateDeletTCB = 12
   667  
   668  	// Existing constants on linux
   669  	BPF_TCP_CLOSE        = 1
   670  	BPF_TCP_LISTEN       = 2
   671  	BPF_TCP_SYN_SENT     = 3
   672  	BPF_TCP_SYN_RECV     = 4
   673  	BPF_TCP_ESTABLISHED  = 5
   674  	BPF_TCP_FIN_WAIT1    = 6
   675  	BPF_TCP_FIN_WAIT2    = 7
   676  	BPF_TCP_CLOSE_WAIT   = 8
   677  	BPF_TCP_LAST_ACK     = 9
   678  	BPF_TCP_CLOSING      = 10
   679  	BPF_TCP_TIME_WAIT    = 11
   680  	BPF_TCP_NEW_SYN_RECV = -1
   681  	BPF_TCP_MAX_STATES   = -2
   682  )
   683  
   684  type nwmTriplet struct {
   685  	offset uint32
   686  	length uint32
   687  	number uint32
   688  }
   689  
   690  type nwmQuadruplet struct {
   691  	offset uint32
   692  	length uint32
   693  	number uint32
   694  	match  uint32
   695  }
   696  
   697  type nwmHeader struct {
   698  	ident       uint32
   699  	length      uint32
   700  	version     uint16
   701  	nwmType     uint16
   702  	bytesNeeded uint32
   703  	options     uint32
   704  	_           [16]byte
   705  	inputDesc   nwmTriplet
   706  	outputDesc  nwmQuadruplet
   707  }
   708  
   709  type nwmFilter struct {
   710  	ident         uint32
   711  	flags         uint32
   712  	resourceName  [8]byte
   713  	resourceId    uint32
   714  	listenerId    uint32
   715  	local         [28]byte // union of sockaddr4 and sockaddr6
   716  	remote        [28]byte // union of sockaddr4 and sockaddr6
   717  	_             uint16
   718  	_             uint16
   719  	asid          uint16
   720  	_             [2]byte
   721  	tnLuName      [8]byte
   722  	tnMonGrp      uint32
   723  	tnAppl        [8]byte
   724  	applData      [40]byte
   725  	nInterface    [16]byte
   726  	dVipa         [16]byte
   727  	dVipaPfx      uint16
   728  	dVipaPort     uint16
   729  	dVipaFamily   byte
   730  	_             [3]byte
   731  	destXCF       [16]byte
   732  	destXCFPfx    uint16
   733  	destXCFFamily byte
   734  	_             [1]byte
   735  	targIP        [16]byte
   736  	targIPPfx     uint16
   737  	targIPFamily  byte
   738  	_             [1]byte
   739  	_             [20]byte
   740  }
   741  
   742  type nwmRecHeader struct {
   743  	ident  uint32
   744  	length uint32
   745  	number byte
   746  	_      [3]byte
   747  }
   748  
   749  type nwmTCPStatsEntry struct {
   750  	ident             uint64
   751  	currEstab         uint32
   752  	activeOpened      uint32
   753  	passiveOpened     uint32
   754  	connClosed        uint32
   755  	estabResets       uint32
   756  	attemptFails      uint32
   757  	passiveDrops      uint32
   758  	timeWaitReused    uint32
   759  	inSegs            uint64
   760  	predictAck        uint32
   761  	predictData       uint32
   762  	inDupAck          uint32
   763  	inBadSum          uint32
   764  	inBadLen          uint32
   765  	inShort           uint32
   766  	inDiscOldTime     uint32
   767  	inAllBeforeWin    uint32
   768  	inSomeBeforeWin   uint32
   769  	inAllAfterWin     uint32
   770  	inSomeAfterWin    uint32
   771  	inOutOfOrder      uint32
   772  	inAfterClose      uint32
   773  	inWinProbes       uint32
   774  	inWinUpdates      uint32
   775  	outWinUpdates     uint32
   776  	outSegs           uint64
   777  	outDelayAcks      uint32
   778  	outRsts           uint32
   779  	retransSegs       uint32
   780  	retransTimeouts   uint32
   781  	retransDrops      uint32
   782  	pmtuRetrans       uint32
   783  	pmtuErrors        uint32
   784  	outWinProbes      uint32
   785  	probeDrops        uint32
   786  	keepAliveProbes   uint32
   787  	keepAliveDrops    uint32
   788  	finwait2Drops     uint32
   789  	acceptCount       uint64
   790  	inBulkQSegs       uint64
   791  	inDiscards        uint64
   792  	connFloods        uint32
   793  	connStalls        uint32
   794  	cfgEphemDef       uint16
   795  	ephemInUse        uint16
   796  	ephemHiWater      uint16
   797  	flags             byte
   798  	_                 [1]byte
   799  	ephemExhaust      uint32
   800  	smcRCurrEstabLnks uint32
   801  	smcRLnkActTimeOut uint32
   802  	smcRActLnkOpened  uint32
   803  	smcRPasLnkOpened  uint32
   804  	smcRLnksClosed    uint32
   805  	smcRCurrEstab     uint32
   806  	smcRActiveOpened  uint32
   807  	smcRPassiveOpened uint32
   808  	smcRConnClosed    uint32
   809  	smcRInSegs        uint64
   810  	smcROutSegs       uint64
   811  	smcRInRsts        uint32
   812  	smcROutRsts       uint32
   813  	smcDCurrEstabLnks uint32
   814  	smcDActLnkOpened  uint32
   815  	smcDPasLnkOpened  uint32
   816  	smcDLnksClosed    uint32
   817  	smcDCurrEstab     uint32
   818  	smcDActiveOpened  uint32
   819  	smcDPassiveOpened uint32
   820  	smcDConnClosed    uint32
   821  	smcDInSegs        uint64
   822  	smcDOutSegs       uint64
   823  	smcDInRsts        uint32
   824  	smcDOutRsts       uint32
   825  }
   826  
   827  type nwmConnEntry struct {
   828  	ident             uint32
   829  	local             [28]byte // union of sockaddr4 and sockaddr6
   830  	remote            [28]byte // union of sockaddr4 and sockaddr6
   831  	startTime         [8]byte  // uint64, changed to prevent padding from being inserted
   832  	lastActivity      [8]byte  // uint64
   833  	bytesIn           [8]byte  // uint64
   834  	bytesOut          [8]byte  // uint64
   835  	inSegs            [8]byte  // uint64
   836  	outSegs           [8]byte  // uint64
   837  	state             uint16
   838  	activeOpen        byte
   839  	flag01            byte
   840  	outBuffered       uint32
   841  	inBuffered        uint32
   842  	maxSndWnd         uint32
   843  	reXmtCount        uint32
   844  	congestionWnd     uint32
   845  	ssThresh          uint32
   846  	roundTripTime     uint32
   847  	roundTripVar      uint32
   848  	sendMSS           uint32
   849  	sndWnd            uint32
   850  	rcvBufSize        uint32
   851  	sndBufSize        uint32
   852  	outOfOrderCount   uint32
   853  	lcl0WindowCount   uint32
   854  	rmt0WindowCount   uint32
   855  	dupacks           uint32
   856  	flag02            byte
   857  	sockOpt6Cont      byte
   858  	asid              uint16
   859  	resourceName      [8]byte
   860  	resourceId        uint32
   861  	subtask           uint32
   862  	sockOpt           byte
   863  	sockOpt6          byte
   864  	clusterConnFlag   byte
   865  	proto             byte
   866  	targetAppl        [8]byte
   867  	luName            [8]byte
   868  	clientUserId      [8]byte
   869  	logMode           [8]byte
   870  	timeStamp         uint32
   871  	timeStampAge      uint32
   872  	serverResourceId  uint32
   873  	intfName          [16]byte
   874  	ttlsStatPol       byte
   875  	ttlsStatConn      byte
   876  	ttlsSSLProt       uint16
   877  	ttlsNegCiph       [2]byte
   878  	ttlsSecType       byte
   879  	ttlsFIPS140Mode   byte
   880  	ttlsUserID        [8]byte
   881  	applData          [40]byte
   882  	inOldestTime      [8]byte // uint64
   883  	outOldestTime     [8]byte // uint64
   884  	tcpTrustedPartner byte
   885  	_                 [3]byte
   886  	bulkDataIntfName  [16]byte
   887  	ttlsNegCiph4      [4]byte
   888  	smcReason         uint32
   889  	lclSMCLinkId      uint32
   890  	rmtSMCLinkId      uint32
   891  	smcStatus         byte
   892  	smcFlags          byte
   893  	_                 [2]byte
   894  	rcvWnd            uint32
   895  	lclSMCBufSz       uint32
   896  	rmtSMCBufSz       uint32
   897  	ttlsSessID        [32]byte
   898  	ttlsSessIDLen     int16
   899  	_                 [1]byte
   900  	smcDStatus        byte
   901  	smcDReason        uint32
   902  }
   903  
   904  var svcNameTable [][]byte = [][]byte{
   905  	[]byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"), // svc_EZBNMIF4
   906  }
   907  
   908  const (
   909  	svc_EZBNMIF4 = 0
   910  )
   911  
   912  func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
   913  	jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40") // "*"
   914  	responseBuffer := [4096]byte{0}
   915  	var bufferAlet, reasonCode uint32 = 0, 0
   916  	var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
   917  
   918  	dsa := [18]uint64{0}
   919  	var argv [7]unsafe.Pointer
   920  	argv[0] = unsafe.Pointer(&jobname[0])
   921  	argv[1] = unsafe.Pointer(&responseBuffer[0])
   922  	argv[2] = unsafe.Pointer(&bufferAlet)
   923  	argv[3] = unsafe.Pointer(&bufferLen)
   924  	argv[4] = unsafe.Pointer(&returnValue)
   925  	argv[5] = unsafe.Pointer(&returnCode)
   926  	argv[6] = unsafe.Pointer(&reasonCode)
   927  
   928  	request := (*struct {
   929  		header nwmHeader
   930  		filter nwmFilter
   931  	})(unsafe.Pointer(&responseBuffer[0]))
   932  
   933  	EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
   934  	if EZBNMIF4 == nil {
   935  		return nil, errnoErr(EINVAL)
   936  	}
   937  
   938  	// GetGlobalStats EZBNMIF4 call
   939  	request.header.ident = nwmHeaderIdentifier
   940  	request.header.length = uint32(unsafe.Sizeof(request.header))
   941  	request.header.version = nwmCurrentVer
   942  	request.header.nwmType = nwmGlobalStatsType
   943  	request.header.options = 0x80000000
   944  
   945  	svcCall(EZBNMIF4, &argv[0], &dsa[0])
   946  
   947  	// outputDesc field is filled by EZBNMIF4 on success
   948  	if returnCode != 0 || request.header.outputDesc.offset == 0 {
   949  		return nil, errnoErr(EINVAL)
   950  	}
   951  
   952  	// Check that EZBNMIF4 returned a nwmRecHeader
   953  	recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
   954  	if recHeader.ident != nwmRecHeaderIdentifier {
   955  		return nil, errnoErr(EINVAL)
   956  	}
   957  
   958  	// Parse nwmTriplets to get offsets of returned entries
   959  	var sections []*uint64
   960  	var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
   961  	for i := uint32(0); i < uint32(recHeader.number); i++ {
   962  		offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
   963  		sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
   964  		for j := uint32(0); j < sectionDesc.number; j++ {
   965  			offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
   966  			sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
   967  		}
   968  	}
   969  
   970  	// Find nwmTCPStatsEntry in returned entries
   971  	var tcpStats *nwmTCPStatsEntry = nil
   972  	for _, ptr := range sections {
   973  		switch *ptr {
   974  		case nwmTCPStatsIdentifier:
   975  			if tcpStats != nil {
   976  				return nil, errnoErr(EINVAL)
   977  			}
   978  			tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
   979  		case nwmIPStatsIdentifier:
   980  		case nwmIPGStatsIdentifier:
   981  		case nwmUDPStatsIdentifier:
   982  		case nwmICMPGStatsEntry:
   983  		case nwmICMPTStatsEntry:
   984  		default:
   985  			return nil, errnoErr(EINVAL)
   986  		}
   987  	}
   988  	if tcpStats == nil {
   989  		return nil, errnoErr(EINVAL)
   990  	}
   991  
   992  	// GetConnectionDetail EZBNMIF4 call
   993  	responseBuffer = [4096]byte{0}
   994  	dsa = [18]uint64{0}
   995  	bufferAlet, reasonCode = 0, 0
   996  	bufferLen, returnValue, returnCode = 4096, 0, 0
   997  	nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process
   998  	nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
   999  	argv[0] = unsafe.Pointer(uintptr(*nameptr))
  1000  
  1001  	request.header.ident = nwmHeaderIdentifier
  1002  	request.header.length = uint32(unsafe.Sizeof(request.header))
  1003  	request.header.version = nwmCurrentVer
  1004  	request.header.nwmType = nwmTCPConnType
  1005  	request.header.options = 0x80000000
  1006  
  1007  	request.filter.ident = nwmFilterIdentifier
  1008  
  1009  	var localSockaddr RawSockaddrAny
  1010  	socklen := _Socklen(SizeofSockaddrAny)
  1011  	err := getsockname(fd, &localSockaddr, &socklen)
  1012  	if err != nil {
  1013  		return nil, errnoErr(EINVAL)
  1014  	}
  1015  	if localSockaddr.Addr.Family == AF_INET {
  1016  		localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
  1017  		localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
  1018  		localSockFilter.Family = AF_INET
  1019  		var i int
  1020  		for i = 0; i < 4; i++ {
  1021  			if localSockaddr.Addr[i] != 0 {
  1022  				break
  1023  			}
  1024  		}
  1025  		if i != 4 {
  1026  			request.filter.flags |= nwmFilterLclAddrMask
  1027  			for i = 0; i < 4; i++ {
  1028  				localSockFilter.Addr[i] = localSockaddr.Addr[i]
  1029  			}
  1030  		}
  1031  		if localSockaddr.Port != 0 {
  1032  			request.filter.flags |= nwmFilterLclPortMask
  1033  			localSockFilter.Port = localSockaddr.Port
  1034  		}
  1035  	} else if localSockaddr.Addr.Family == AF_INET6 {
  1036  		localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
  1037  		localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
  1038  		localSockFilter.Family = AF_INET6
  1039  		var i int
  1040  		for i = 0; i < 16; i++ {
  1041  			if localSockaddr.Addr[i] != 0 {
  1042  				break
  1043  			}
  1044  		}
  1045  		if i != 16 {
  1046  			request.filter.flags |= nwmFilterLclAddrMask
  1047  			for i = 0; i < 16; i++ {
  1048  				localSockFilter.Addr[i] = localSockaddr.Addr[i]
  1049  			}
  1050  		}
  1051  		if localSockaddr.Port != 0 {
  1052  			request.filter.flags |= nwmFilterLclPortMask
  1053  			localSockFilter.Port = localSockaddr.Port
  1054  		}
  1055  	}
  1056  
  1057  	svcCall(EZBNMIF4, &argv[0], &dsa[0])
  1058  
  1059  	// outputDesc field is filled by EZBNMIF4 on success
  1060  	if returnCode != 0 || request.header.outputDesc.offset == 0 {
  1061  		return nil, errnoErr(EINVAL)
  1062  	}
  1063  
  1064  	// Check that EZBNMIF4 returned a nwmConnEntry
  1065  	conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
  1066  	if conn.ident != nwmTCPConnIdentifier {
  1067  		return nil, errnoErr(EINVAL)
  1068  	}
  1069  
  1070  	// Copy data from the returned data structures into tcpInfo
  1071  	// Stats from nwmConnEntry are specific to that connection.
  1072  	// Stats from nwmTCPStatsEntry are global (to the interface?)
  1073  	// Fields may not be an exact match. Some fields have no equivalent.
  1074  	var tcpinfo TCPInfo
  1075  	tcpinfo.State = uint8(conn.state)
  1076  	tcpinfo.Ca_state = 0 // dummy
  1077  	tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
  1078  	tcpinfo.Probes = uint8(tcpStats.outWinProbes)
  1079  	tcpinfo.Backoff = 0 // dummy
  1080  	tcpinfo.Options = 0 // dummy
  1081  	tcpinfo.Rto = tcpStats.retransTimeouts
  1082  	tcpinfo.Ato = tcpStats.outDelayAcks
  1083  	tcpinfo.Snd_mss = conn.sendMSS
  1084  	tcpinfo.Rcv_mss = conn.sendMSS // dummy
  1085  	tcpinfo.Unacked = 0            // dummy
  1086  	tcpinfo.Sacked = 0             // dummy
  1087  	tcpinfo.Lost = 0               // dummy
  1088  	tcpinfo.Retrans = conn.reXmtCount
  1089  	tcpinfo.Fackets = 0 // dummy
  1090  	tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
  1091  	tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
  1092  	tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  1093  	tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  1094  	tcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate
  1095  	tcpinfo.Rcv_ssthresh = conn.ssThresh
  1096  	tcpinfo.Rtt = conn.roundTripTime
  1097  	tcpinfo.Rttvar = conn.roundTripVar
  1098  	tcpinfo.Snd_ssthresh = conn.ssThresh // dummy
  1099  	tcpinfo.Snd_cwnd = conn.congestionWnd
  1100  	tcpinfo.Advmss = conn.sendMSS        // dummy
  1101  	tcpinfo.Reordering = 0               // dummy
  1102  	tcpinfo.Rcv_rtt = conn.roundTripTime // dummy
  1103  	tcpinfo.Rcv_space = conn.sendMSS     // dummy
  1104  	tcpinfo.Total_retrans = conn.reXmtCount
  1105  
  1106  	svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
  1107  
  1108  	return &tcpinfo, nil
  1109  }
  1110  
  1111  // GetsockoptString returns the string value of the socket option opt for the
  1112  // socket associated with fd at the given socket level.
  1113  func GetsockoptString(fd, level, opt int) (string, error) {
  1114  	buf := make([]byte, 256)
  1115  	vallen := _Socklen(len(buf))
  1116  	err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
  1117  	if err != nil {
  1118  		return "", err
  1119  	}
  1120  
  1121  	return string(buf[:vallen-1]), nil
  1122  }
  1123  
  1124  func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  1125  	var msg Msghdr
  1126  	var rsa RawSockaddrAny
  1127  	msg.Name = (*byte)(unsafe.Pointer(&rsa))
  1128  	msg.Namelen = SizeofSockaddrAny
  1129  	var iov Iovec
  1130  	if len(p) > 0 {
  1131  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1132  		iov.SetLen(len(p))
  1133  	}
  1134  	var dummy byte
  1135  	if len(oob) > 0 {
  1136  		// receive at least one normal byte
  1137  		if len(p) == 0 {
  1138  			iov.Base = &dummy
  1139  			iov.SetLen(1)
  1140  		}
  1141  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1142  		msg.SetControllen(len(oob))
  1143  	}
  1144  	msg.Iov = &iov
  1145  	msg.Iovlen = 1
  1146  	if n, err = recvmsg(fd, &msg, flags); err != nil {
  1147  		return
  1148  	}
  1149  	oobn = int(msg.Controllen)
  1150  	recvflags = int(msg.Flags)
  1151  	// source address is only specified if the socket is unconnected
  1152  	if rsa.Addr.Family != AF_UNSPEC {
  1153  		// TODO(neeilan): Remove 0 arg added to get this compiling on z/OS
  1154  		from, err = anyToSockaddr(0, &rsa)
  1155  	}
  1156  	return
  1157  }
  1158  
  1159  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
  1160  	_, err = SendmsgN(fd, p, oob, to, flags)
  1161  	return
  1162  }
  1163  
  1164  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
  1165  	var ptr unsafe.Pointer
  1166  	var salen _Socklen
  1167  	if to != nil {
  1168  		var err error
  1169  		ptr, salen, err = to.sockaddr()
  1170  		if err != nil {
  1171  			return 0, err
  1172  		}
  1173  	}
  1174  	var msg Msghdr
  1175  	msg.Name = (*byte)(unsafe.Pointer(ptr))
  1176  	msg.Namelen = int32(salen)
  1177  	var iov Iovec
  1178  	if len(p) > 0 {
  1179  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1180  		iov.SetLen(len(p))
  1181  	}
  1182  	var dummy byte
  1183  	if len(oob) > 0 {
  1184  		// send at least one normal byte
  1185  		if len(p) == 0 {
  1186  			iov.Base = &dummy
  1187  			iov.SetLen(1)
  1188  		}
  1189  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1190  		msg.SetControllen(len(oob))
  1191  	}
  1192  	msg.Iov = &iov
  1193  	msg.Iovlen = 1
  1194  	if n, err = sendmsg(fd, &msg, flags); err != nil {
  1195  		return 0, err
  1196  	}
  1197  	if len(oob) > 0 && len(p) == 0 {
  1198  		n = 0
  1199  	}
  1200  	return n, nil
  1201  }
  1202  
  1203  func Opendir(name string) (uintptr, error) {
  1204  	p, err := BytePtrFromString(name)
  1205  	if err != nil {
  1206  		return 0, err
  1207  	}
  1208  	dir, _, e := syscall_syscall(SYS___OPENDIR_A, uintptr(unsafe.Pointer(p)), 0, 0)
  1209  	runtime.KeepAlive(unsafe.Pointer(p))
  1210  	if e != 0 {
  1211  		err = errnoErr(e)
  1212  	}
  1213  	return dir, err
  1214  }
  1215  
  1216  // clearsyscall.Errno resets the errno value to 0.
  1217  func clearErrno()
  1218  
  1219  func Readdir(dir uintptr) (*Dirent, error) {
  1220  	var ent Dirent
  1221  	var res uintptr
  1222  	// __readdir_r_a returns errno at the end of the directory stream, rather than 0.
  1223  	// Therefore to avoid false positives we clear errno before calling it.
  1224  
  1225  	// TODO(neeilan): Commented this out to get sys/unix compiling on z/OS. Uncomment and fix. Error: "undefined: clearsyscall"
  1226  	//clearsyscall.Errno() // TODO(mundaym): check pre-emption rules.
  1227  
  1228  	e, _, _ := syscall_syscall(SYS___READDIR_R_A, dir, uintptr(unsafe.Pointer(&ent)), uintptr(unsafe.Pointer(&res)))
  1229  	var err error
  1230  	if e != 0 {
  1231  		err = errnoErr(Errno(e))
  1232  	}
  1233  	if res == 0 {
  1234  		return nil, err
  1235  	}
  1236  	return &ent, err
  1237  }
  1238  
  1239  func Closedir(dir uintptr) error {
  1240  	_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
  1241  	if e != 0 {
  1242  		return errnoErr(e)
  1243  	}
  1244  	return nil
  1245  }
  1246  
  1247  func Seekdir(dir uintptr, pos int) {
  1248  	_, _, _ = syscall_syscall(SYS_SEEKDIR, dir, uintptr(pos), 0)
  1249  }
  1250  
  1251  func Telldir(dir uintptr) (int, error) {
  1252  	p, _, e := syscall_syscall(SYS_TELLDIR, dir, 0, 0)
  1253  	pos := int(p)
  1254  	if pos == -1 {
  1255  		return pos, errnoErr(e)
  1256  	}
  1257  	return pos, nil
  1258  }
  1259  
  1260  // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
  1261  func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
  1262  	// struct flock is packed on z/OS. We can't emulate that in Go so
  1263  	// instead we pack it here.
  1264  	var flock [24]byte
  1265  	*(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
  1266  	*(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
  1267  	*(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
  1268  	*(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
  1269  	*(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
  1270  	_, _, errno := syscall_syscall(SYS_FCNTL, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
  1271  	lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
  1272  	lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
  1273  	lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
  1274  	lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
  1275  	lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
  1276  	if errno == 0 {
  1277  		return nil
  1278  	}
  1279  	return errno
  1280  }
  1281  
  1282  func Flock(fd int, how int) error {
  1283  
  1284  	var flock_type int16
  1285  	var fcntl_cmd int
  1286  
  1287  	switch how {
  1288  	case LOCK_SH | LOCK_NB:
  1289  		flock_type = F_RDLCK
  1290  		fcntl_cmd = F_SETLK
  1291  	case LOCK_EX | LOCK_NB:
  1292  		flock_type = F_WRLCK
  1293  		fcntl_cmd = F_SETLK
  1294  	case LOCK_EX:
  1295  		flock_type = F_WRLCK
  1296  		fcntl_cmd = F_SETLKW
  1297  	case LOCK_UN:
  1298  		flock_type = F_UNLCK
  1299  		fcntl_cmd = F_SETLKW
  1300  	default:
  1301  	}
  1302  
  1303  	flock := Flock_t{
  1304  		Type:   int16(flock_type),
  1305  		Whence: int16(0),
  1306  		Start:  int64(0),
  1307  		Len:    int64(0),
  1308  		Pid:    int32(Getppid()),
  1309  	}
  1310  
  1311  	err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
  1312  	return err
  1313  }
  1314  
  1315  func Mlock(b []byte) (err error) {
  1316  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
  1317  	if e1 != 0 {
  1318  		err = errnoErr(e1)
  1319  	}
  1320  	return
  1321  }
  1322  
  1323  func Mlock2(b []byte, flags int) (err error) {
  1324  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
  1325  	if e1 != 0 {
  1326  		err = errnoErr(e1)
  1327  	}
  1328  	return
  1329  }
  1330  
  1331  func Mlockall(flags int) (err error) {
  1332  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
  1333  	if e1 != 0 {
  1334  		err = errnoErr(e1)
  1335  	}
  1336  	return
  1337  }
  1338  
  1339  func Munlock(b []byte) (err error) {
  1340  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
  1341  	if e1 != 0 {
  1342  		err = errnoErr(e1)
  1343  	}
  1344  	return
  1345  }
  1346  
  1347  func Munlockall() (err error) {
  1348  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
  1349  	if e1 != 0 {
  1350  		err = errnoErr(e1)
  1351  	}
  1352  	return
  1353  }
  1354  
  1355  func ClockGettime(clockid int32, ts *Timespec) error {
  1356  
  1357  	var ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise
  1358  	var nsec_per_sec int64 = 1000000000
  1359  
  1360  	if ts == nil {
  1361  		return EFAULT
  1362  	}
  1363  	if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
  1364  		var nanotime int64 = runtime.Nanotime1()
  1365  		ts.Sec = nanotime / nsec_per_sec
  1366  		ts.Nsec = nanotime % nsec_per_sec
  1367  	} else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
  1368  		var tm Tms
  1369  		_, err := Times(&tm)
  1370  		if err != nil {
  1371  			return EFAULT
  1372  		}
  1373  		ts.Sec = int64(tm.Utime / ticks_per_sec)
  1374  		ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
  1375  	} else {
  1376  		return EINVAL
  1377  	}
  1378  	return nil
  1379  }
  1380  
  1381  func Statfs(path string, stat *Statfs_t) (err error) {
  1382  	fd, err := open(path, O_RDONLY, 0)
  1383  	defer Close(fd)
  1384  	if err != nil {
  1385  		return err
  1386  	}
  1387  	return Fstatfs(fd, stat)
  1388  }
  1389  
  1390  var (
  1391  	Stdin  = 0
  1392  	Stdout = 1
  1393  	Stderr = 2
  1394  )
  1395  
  1396  // Do the interface allocations only once for common
  1397  // Errno values.
  1398  var (
  1399  	errEAGAIN error = syscall.EAGAIN
  1400  	errEINVAL error = syscall.EINVAL
  1401  	errENOENT error = syscall.ENOENT
  1402  )
  1403  
  1404  var (
  1405  	signalNameMapOnce sync.Once
  1406  	signalNameMap     map[string]syscall.Signal
  1407  )
  1408  
  1409  // errnoErr returns common boxed Errno values, to prevent
  1410  // allocations at runtime.
  1411  func errnoErr(e Errno) error {
  1412  	switch e {
  1413  	case 0:
  1414  		return nil
  1415  	case EAGAIN:
  1416  		return errEAGAIN
  1417  	case EINVAL:
  1418  		return errEINVAL
  1419  	case ENOENT:
  1420  		return errENOENT
  1421  	}
  1422  	return e
  1423  }
  1424  
  1425  // ErrnoName returns the error name for error number e.
  1426  func ErrnoName(e Errno) string {
  1427  	i := sort.Search(len(errorList), func(i int) bool {
  1428  		return errorList[i].num >= e
  1429  	})
  1430  	if i < len(errorList) && errorList[i].num == e {
  1431  		return errorList[i].name
  1432  	}
  1433  	return ""
  1434  }
  1435  
  1436  // SignalName returns the signal name for signal number s.
  1437  func SignalName(s syscall.Signal) string {
  1438  	i := sort.Search(len(signalList), func(i int) bool {
  1439  		return signalList[i].num >= s
  1440  	})
  1441  	if i < len(signalList) && signalList[i].num == s {
  1442  		return signalList[i].name
  1443  	}
  1444  	return ""
  1445  }
  1446  
  1447  // SignalNum returns the syscall.Signal for signal named s,
  1448  // or 0 if a signal with such name is not found.
  1449  // The signal name should start with "SIG".
  1450  func SignalNum(s string) syscall.Signal {
  1451  	signalNameMapOnce.Do(func() {
  1452  		signalNameMap = make(map[string]syscall.Signal, len(signalList))
  1453  		for _, signal := range signalList {
  1454  			signalNameMap[signal.name] = signal.num
  1455  		}
  1456  	})
  1457  	return signalNameMap[s]
  1458  }
  1459  
  1460  // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
  1461  func clen(n []byte) int {
  1462  	i := bytes.IndexByte(n, 0)
  1463  	if i == -1 {
  1464  		i = len(n)
  1465  	}
  1466  	return i
  1467  }
  1468  
  1469  // Mmap manager, for use by operating system-specific implementations.
  1470  
  1471  type mmapper struct {
  1472  	sync.Mutex
  1473  	active map[*byte][]byte // active mappings; key is last byte in mapping
  1474  	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
  1475  	munmap func(addr uintptr, length uintptr) error
  1476  }
  1477  
  1478  func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  1479  	if length <= 0 {
  1480  		return nil, EINVAL
  1481  	}
  1482  
  1483  	// Map the requested memory.
  1484  	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
  1485  	if errno != nil {
  1486  		return nil, errno
  1487  	}
  1488  
  1489  	// Slice memory layout
  1490  	var sl = struct {
  1491  		addr uintptr
  1492  		len  int
  1493  		cap  int
  1494  	}{addr, length, length}
  1495  
  1496  	// Use unsafe to turn sl into a []byte.
  1497  	b := *(*[]byte)(unsafe.Pointer(&sl))
  1498  
  1499  	// Register mapping in m and return it.
  1500  	p := &b[cap(b)-1]
  1501  	m.Lock()
  1502  	defer m.Unlock()
  1503  	m.active[p] = b
  1504  	return b, nil
  1505  }
  1506  
  1507  func (m *mmapper) Munmap(data []byte) (err error) {
  1508  	if len(data) == 0 || len(data) != cap(data) {
  1509  		return EINVAL
  1510  	}
  1511  
  1512  	// Find the base of the mapping.
  1513  	p := &data[cap(data)-1]
  1514  	m.Lock()
  1515  	defer m.Unlock()
  1516  	b := m.active[p]
  1517  	if b == nil || &b[0] != &data[0] {
  1518  		return EINVAL
  1519  	}
  1520  
  1521  	// Unmap the memory and update m.
  1522  	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
  1523  		return errno
  1524  	}
  1525  	delete(m.active, p)
  1526  	return nil
  1527  }
  1528  
  1529  func Read(fd int, p []byte) (n int, err error) {
  1530  	n, err = read(fd, p)
  1531  	if raceenabled {
  1532  		if n > 0 {
  1533  			raceWriteRange(unsafe.Pointer(&p[0]), n)
  1534  		}
  1535  		if err == nil {
  1536  			raceAcquire(unsafe.Pointer(&ioSync))
  1537  		}
  1538  	}
  1539  	return
  1540  }
  1541  
  1542  func Write(fd int, p []byte) (n int, err error) {
  1543  	if raceenabled {
  1544  		raceReleaseMerge(unsafe.Pointer(&ioSync))
  1545  	}
  1546  	n, err = write(fd, p)
  1547  	if raceenabled && n > 0 {
  1548  		raceReadRange(unsafe.Pointer(&p[0]), n)
  1549  	}
  1550  	return
  1551  }
  1552  
  1553  // For testing: clients can set this flag to force
  1554  // creation of IPv6 sockets to return EAFNOSUPPORT.
  1555  var SocketDisableIPv6 bool
  1556  
  1557  // Sockaddr represents a socket address.
  1558  type Sockaddr interface {
  1559  	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
  1560  }
  1561  
  1562  // SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
  1563  type SockaddrInet4 struct {
  1564  	Port int
  1565  	Addr [4]byte
  1566  	raw  RawSockaddrInet4
  1567  }
  1568  
  1569  // SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
  1570  type SockaddrInet6 struct {
  1571  	Port   int
  1572  	ZoneId uint32
  1573  	Addr   [16]byte
  1574  	raw    RawSockaddrInet6
  1575  }
  1576  
  1577  // SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
  1578  type SockaddrUnix struct {
  1579  	Name string
  1580  	raw  RawSockaddrUnix
  1581  }
  1582  
  1583  func Bind(fd int, sa Sockaddr) (err error) {
  1584  	ptr, n, err := sa.sockaddr()
  1585  	if err != nil {
  1586  		return err
  1587  	}
  1588  	return bind(fd, ptr, n)
  1589  }
  1590  
  1591  func Connect(fd int, sa Sockaddr) (err error) {
  1592  	ptr, n, err := sa.sockaddr()
  1593  	if err != nil {
  1594  		return err
  1595  	}
  1596  	return connect(fd, ptr, n)
  1597  }
  1598  
  1599  func Getpeername(fd int) (sa Sockaddr, err error) {
  1600  	var rsa RawSockaddrAny
  1601  	var len _Socklen = SizeofSockaddrAny
  1602  	if err = getpeername(fd, &rsa, &len); err != nil {
  1603  		return
  1604  	}
  1605  	return anyToSockaddr(fd, &rsa)
  1606  }
  1607  
  1608  func GetsockoptByte(fd, level, opt int) (value byte, err error) {
  1609  	var n byte
  1610  	vallen := _Socklen(1)
  1611  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1612  	return n, err
  1613  }
  1614  
  1615  func GetsockoptInt(fd, level, opt int) (value int, err error) {
  1616  	var n int32
  1617  	vallen := _Socklen(4)
  1618  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1619  	return int(n), err
  1620  }
  1621  
  1622  func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
  1623  	vallen := _Socklen(4)
  1624  	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
  1625  	return value, err
  1626  }
  1627  
  1628  func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
  1629  	var value IPMreq
  1630  	vallen := _Socklen(SizeofIPMreq)
  1631  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1632  	return &value, err
  1633  }
  1634  
  1635  func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
  1636  	var value IPv6Mreq
  1637  	vallen := _Socklen(SizeofIPv6Mreq)
  1638  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1639  	return &value, err
  1640  }
  1641  
  1642  func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
  1643  	var value IPv6MTUInfo
  1644  	vallen := _Socklen(SizeofIPv6MTUInfo)
  1645  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1646  	return &value, err
  1647  }
  1648  
  1649  func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
  1650  	var value ICMPv6Filter
  1651  	vallen := _Socklen(SizeofICMPv6Filter)
  1652  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1653  	return &value, err
  1654  }
  1655  
  1656  func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
  1657  	var linger Linger
  1658  	vallen := _Socklen(SizeofLinger)
  1659  	err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
  1660  	return &linger, err
  1661  }
  1662  
  1663  func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
  1664  	var tv Timeval
  1665  	vallen := _Socklen(unsafe.Sizeof(tv))
  1666  	err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
  1667  	return &tv, err
  1668  }
  1669  
  1670  func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
  1671  	var n uint64
  1672  	vallen := _Socklen(8)
  1673  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1674  	return n, err
  1675  }
  1676  
  1677  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
  1678  	var rsa RawSockaddrAny
  1679  	var len _Socklen = SizeofSockaddrAny
  1680  	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
  1681  		return
  1682  	}
  1683  	if rsa.Addr.Family != AF_UNSPEC {
  1684  		from, err = anyToSockaddr(fd, &rsa)
  1685  	}
  1686  	return
  1687  }
  1688  
  1689  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
  1690  	ptr, n, err := to.sockaddr()
  1691  	if err != nil {
  1692  		return err
  1693  	}
  1694  	return sendto(fd, p, flags, ptr, n)
  1695  }
  1696  
  1697  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
  1698  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
  1699  }
  1700  
  1701  func SetsockoptInt(fd, level, opt int, value int) (err error) {
  1702  	var n = int32(value)
  1703  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
  1704  }
  1705  
  1706  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
  1707  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
  1708  }
  1709  
  1710  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
  1711  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
  1712  }
  1713  
  1714  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
  1715  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
  1716  }
  1717  
  1718  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
  1719  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
  1720  }
  1721  
  1722  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
  1723  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
  1724  }
  1725  
  1726  func SetsockoptString(fd, level, opt int, s string) (err error) {
  1727  	var p unsafe.Pointer
  1728  	if len(s) > 0 {
  1729  		p = unsafe.Pointer(&[]byte(s)[0])
  1730  	}
  1731  	return setsockopt(fd, level, opt, p, uintptr(len(s)))
  1732  }
  1733  
  1734  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
  1735  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
  1736  }
  1737  
  1738  func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
  1739  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
  1740  }
  1741  
  1742  func Socket(domain, typ, proto int) (fd int, err error) {
  1743  	if domain == AF_INET6 && SocketDisableIPv6 {
  1744  		return -1, EAFNOSUPPORT
  1745  	}
  1746  	fd, err = socket(domain, typ, proto)
  1747  	return
  1748  }
  1749  
  1750  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
  1751  	var fdx [2]int32
  1752  	err = socketpair(domain, typ, proto, &fdx)
  1753  	if err == nil {
  1754  		fd[0] = int(fdx[0])
  1755  		fd[1] = int(fdx[1])
  1756  	}
  1757  	return
  1758  }
  1759  
  1760  var ioSync int64
  1761  
  1762  func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
  1763  
  1764  func SetNonblock(fd int, nonblocking bool) (err error) {
  1765  	flag, err := fcntl(fd, F_GETFL, 0)
  1766  	if err != nil {
  1767  		return err
  1768  	}
  1769  	if nonblocking {
  1770  		flag |= O_NONBLOCK
  1771  	} else {
  1772  		flag &= ^O_NONBLOCK
  1773  	}
  1774  	_, err = fcntl(fd, F_SETFL, flag)
  1775  	return err
  1776  }
  1777  
  1778  // Exec calls execve(2), which replaces the calling executable in the process
  1779  // tree. argv0 should be the full path to an executable ("/bin/ls") and the
  1780  // executable name should also be the first argument in argv (["ls", "-l"]).
  1781  // envv are the environment variables that should be passed to the new
  1782  // process (["USER=go", "PWD=/tmp"]).
  1783  func Exec(argv0 string, argv []string, envv []string) error {
  1784  	return syscall.Exec(argv0, argv, envv)
  1785  }
  1786  
  1787  func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  1788  	if needspace := 8 - len(fstype); needspace <= 0 {
  1789  		fstype = fstype[:8]
  1790  	} else {
  1791  		fstype += "        "[:needspace]
  1792  	}
  1793  	return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
  1794  }
  1795  
  1796  func Unmount(name string, mtm int) (err error) {
  1797  	// mountpoint is always a full path and starts with a '/'
  1798  	// check if input string is not a mountpoint but a filesystem name
  1799  	if name[0] != '/' {
  1800  		return unmount(name, mtm)
  1801  	}
  1802  	// treat name as mountpoint
  1803  	b2s := func(arr []byte) string {
  1804  		nulli := bytes.IndexByte(arr, 0)
  1805  		if nulli == -1 {
  1806  			return string(arr)
  1807  		} else {
  1808  			return string(arr[:nulli])
  1809  		}
  1810  	}
  1811  	var buffer struct {
  1812  		header W_Mnth
  1813  		fsinfo [64]W_Mntent
  1814  	}
  1815  	fsCount, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
  1816  	if err != nil {
  1817  		return err
  1818  	}
  1819  	if fsCount == 0 {
  1820  		return EINVAL
  1821  	}
  1822  	for i := 0; i < fsCount; i++ {
  1823  		if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
  1824  			err = unmount(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
  1825  			break
  1826  		}
  1827  	}
  1828  	return err
  1829  }