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