golang.org/x/sys@v0.9.0/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  	"fmt"
    13  	"runtime"
    14  	"sort"
    15  	"strings"
    16  	"sync"
    17  	"syscall"
    18  	"unsafe"
    19  )
    20  
    21  const (
    22  	O_CLOEXEC = 0       // Dummy value (not supported).
    23  	AF_LOCAL  = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
    24  )
    25  
    26  func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    27  func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    28  func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    29  func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    30  func syscall_syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
    31  func syscall_rawsyscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
    32  
    33  func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
    34  	stat.Dev = uint64(statLE.Dev)
    35  	stat.Ino = uint64(statLE.Ino)
    36  	stat.Nlink = uint64(statLE.Nlink)
    37  	stat.Mode = uint32(statLE.Mode)
    38  	stat.Uid = uint32(statLE.Uid)
    39  	stat.Gid = uint32(statLE.Gid)
    40  	stat.Rdev = uint64(statLE.Rdev)
    41  	stat.Size = statLE.Size
    42  	stat.Atim.Sec = int64(statLE.Atim)
    43  	stat.Atim.Nsec = 0 //zos doesn't return nanoseconds
    44  	stat.Mtim.Sec = int64(statLE.Mtim)
    45  	stat.Mtim.Nsec = 0 //zos doesn't return nanoseconds
    46  	stat.Ctim.Sec = int64(statLE.Ctim)
    47  	stat.Ctim.Nsec = 0 //zos doesn't return nanoseconds
    48  	stat.Blksize = int64(statLE.Blksize)
    49  	stat.Blocks = statLE.Blocks
    50  }
    51  
    52  func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
    53  func svcLoad(name *byte) unsafe.Pointer
    54  func svcUnload(name *byte, fnptr unsafe.Pointer) int64
    55  
    56  func (d *Dirent) NameString() string {
    57  	if d == nil {
    58  		return ""
    59  	}
    60  	s := string(d.Name[:])
    61  	idx := strings.IndexByte(s, 0)
    62  	if idx == -1 {
    63  		return s
    64  	} else {
    65  		return s[:idx]
    66  	}
    67  }
    68  
    69  func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
    70  	if sa.Port < 0 || sa.Port > 0xFFFF {
    71  		return nil, 0, EINVAL
    72  	}
    73  	sa.raw.Len = SizeofSockaddrInet4
    74  	sa.raw.Family = AF_INET
    75  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
    76  	p[0] = byte(sa.Port >> 8)
    77  	p[1] = byte(sa.Port)
    78  	sa.raw.Addr = sa.Addr
    79  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
    80  }
    81  
    82  func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
    83  	if sa.Port < 0 || sa.Port > 0xFFFF {
    84  		return nil, 0, EINVAL
    85  	}
    86  	sa.raw.Len = SizeofSockaddrInet6
    87  	sa.raw.Family = AF_INET6
    88  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
    89  	p[0] = byte(sa.Port >> 8)
    90  	p[1] = byte(sa.Port)
    91  	sa.raw.Scope_id = sa.ZoneId
    92  	sa.raw.Addr = sa.Addr
    93  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
    94  }
    95  
    96  func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
    97  	name := sa.Name
    98  	n := len(name)
    99  	if n >= len(sa.raw.Path) || n == 0 {
   100  		return nil, 0, EINVAL
   101  	}
   102  	sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
   103  	sa.raw.Family = AF_UNIX
   104  	for i := 0; i < n; i++ {
   105  		sa.raw.Path[i] = int8(name[i])
   106  	}
   107  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
   108  }
   109  
   110  func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
   111  	// TODO(neeilan): Implement use of first param (fd)
   112  	switch rsa.Addr.Family {
   113  	case AF_UNIX:
   114  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
   115  		sa := new(SockaddrUnix)
   116  		// For z/OS, only replace NUL with @ when the
   117  		// length is not zero.
   118  		if pp.Len != 0 && pp.Path[0] == 0 {
   119  			// "Abstract" Unix domain socket.
   120  			// Rewrite leading NUL as @ for textual display.
   121  			// (This is the standard convention.)
   122  			// Not friendly to overwrite in place,
   123  			// but the callers below don't care.
   124  			pp.Path[0] = '@'
   125  		}
   126  
   127  		// Assume path ends at NUL.
   128  		//
   129  		// For z/OS, the length of the name is a field
   130  		// in the structure. To be on the safe side, we
   131  		// will still scan the name for a NUL but only
   132  		// to the length provided in the structure.
   133  		//
   134  		// This is not technically the Linux semantics for
   135  		// abstract Unix domain sockets--they are supposed
   136  		// to be uninterpreted fixed-size binary blobs--but
   137  		// everyone uses this convention.
   138  		n := 0
   139  		for n < int(pp.Len) && pp.Path[n] != 0 {
   140  			n++
   141  		}
   142  		sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
   143  		return sa, nil
   144  
   145  	case AF_INET:
   146  		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
   147  		sa := new(SockaddrInet4)
   148  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   149  		sa.Port = int(p[0])<<8 + int(p[1])
   150  		sa.Addr = pp.Addr
   151  		return sa, nil
   152  
   153  	case AF_INET6:
   154  		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
   155  		sa := new(SockaddrInet6)
   156  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
   157  		sa.Port = int(p[0])<<8 + int(p[1])
   158  		sa.ZoneId = pp.Scope_id
   159  		sa.Addr = pp.Addr
   160  		return sa, nil
   161  	}
   162  	return nil, EAFNOSUPPORT
   163  }
   164  
   165  func Accept(fd int) (nfd int, sa Sockaddr, err error) {
   166  	var rsa RawSockaddrAny
   167  	var len _Socklen = SizeofSockaddrAny
   168  	nfd, err = accept(fd, &rsa, &len)
   169  	if err != nil {
   170  		return
   171  	}
   172  	// TODO(neeilan): Remove 0 in call
   173  	sa, err = anyToSockaddr(0, &rsa)
   174  	if err != nil {
   175  		Close(nfd)
   176  		nfd = 0
   177  	}
   178  	return
   179  }
   180  
   181  func (iov *Iovec) SetLen(length int) {
   182  	iov.Len = uint64(length)
   183  }
   184  
   185  func (msghdr *Msghdr) SetControllen(length int) {
   186  	msghdr.Controllen = int32(length)
   187  }
   188  
   189  func (cmsg *Cmsghdr) SetLen(length int) {
   190  	cmsg.Len = int32(length)
   191  }
   192  
   193  //sys   fcntl(fd int, cmd int, arg int) (val int, err error)
   194  //sys	read(fd int, p []byte) (n int, err error)
   195  //sys   readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
   196  //sys	write(fd int, p []byte) (n int, err error)
   197  
   198  //sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A
   199  //sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A
   200  //sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A
   201  //sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
   202  //sysnb	setgroups(n int, list *_Gid_t) (err error)
   203  //sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
   204  //sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
   205  //sysnb	socket(domain int, typ int, proto int) (fd int, err error)
   206  //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
   207  //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A
   208  //sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A
   209  //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A
   210  //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A
   211  //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A
   212  //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A
   213  //sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP
   214  //sys   munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP
   215  //sys   ioctl(fd int, req int, arg uintptr) (err error) = SYS_IOCTL
   216  //sys   ioctlPtr(fd int, req int, arg unsafe.Pointer) (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  	if err == nil {
   591  		p[0] = int(pp[0])
   592  		p[1] = int(pp[1])
   593  	}
   594  	return
   595  }
   596  
   597  //sys	utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
   598  
   599  func Utimes(path string, tv []Timeval) (err error) {
   600  	if len(tv) != 2 {
   601  		return EINVAL
   602  	}
   603  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   604  }
   605  
   606  func UtimesNano(path string, ts []Timespec) error {
   607  	if len(ts) != 2 {
   608  		return EINVAL
   609  	}
   610  	// Not as efficient as it could be because Timespec and
   611  	// Timeval have different types in the different OSes
   612  	tv := [2]Timeval{
   613  		NsecToTimeval(TimespecToNsec(ts[0])),
   614  		NsecToTimeval(TimespecToNsec(ts[1])),
   615  	}
   616  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
   617  }
   618  
   619  func Getsockname(fd int) (sa Sockaddr, err error) {
   620  	var rsa RawSockaddrAny
   621  	var len _Socklen = SizeofSockaddrAny
   622  	if err = getsockname(fd, &rsa, &len); err != nil {
   623  		return
   624  	}
   625  	// TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )
   626  	return anyToSockaddr(0, &rsa)
   627  }
   628  
   629  const (
   630  	// identifier constants
   631  	nwmHeaderIdentifier    = 0xd5e6d4c8
   632  	nwmFilterIdentifier    = 0xd5e6d4c6
   633  	nwmTCPConnIdentifier   = 0xd5e6d4c3
   634  	nwmRecHeaderIdentifier = 0xd5e6d4d9
   635  	nwmIPStatsIdentifier   = 0xd5e6d4c9d7e2e340
   636  	nwmIPGStatsIdentifier  = 0xd5e6d4c9d7c7e2e3
   637  	nwmTCPStatsIdentifier  = 0xd5e6d4e3c3d7e2e3
   638  	nwmUDPStatsIdentifier  = 0xd5e6d4e4c4d7e2e3
   639  	nwmICMPGStatsEntry     = 0xd5e6d4c9c3d4d7c7
   640  	nwmICMPTStatsEntry     = 0xd5e6d4c9c3d4d7e3
   641  
   642  	// nwmHeader constants
   643  	nwmVersion1   = 1
   644  	nwmVersion2   = 2
   645  	nwmCurrentVer = 2
   646  
   647  	nwmTCPConnType     = 1
   648  	nwmGlobalStatsType = 14
   649  
   650  	// nwmFilter constants
   651  	nwmFilterLclAddrMask = 0x20000000 // Local address
   652  	nwmFilterSrcAddrMask = 0x20000000 // Source address
   653  	nwmFilterLclPortMask = 0x10000000 // Local port
   654  	nwmFilterSrcPortMask = 0x10000000 // Source port
   655  
   656  	// nwmConnEntry constants
   657  	nwmTCPStateClosed   = 1
   658  	nwmTCPStateListen   = 2
   659  	nwmTCPStateSynSent  = 3
   660  	nwmTCPStateSynRcvd  = 4
   661  	nwmTCPStateEstab    = 5
   662  	nwmTCPStateFinWait1 = 6
   663  	nwmTCPStateFinWait2 = 7
   664  	nwmTCPStateClosWait = 8
   665  	nwmTCPStateLastAck  = 9
   666  	nwmTCPStateClosing  = 10
   667  	nwmTCPStateTimeWait = 11
   668  	nwmTCPStateDeletTCB = 12
   669  
   670  	// Existing constants on linux
   671  	BPF_TCP_CLOSE        = 1
   672  	BPF_TCP_LISTEN       = 2
   673  	BPF_TCP_SYN_SENT     = 3
   674  	BPF_TCP_SYN_RECV     = 4
   675  	BPF_TCP_ESTABLISHED  = 5
   676  	BPF_TCP_FIN_WAIT1    = 6
   677  	BPF_TCP_FIN_WAIT2    = 7
   678  	BPF_TCP_CLOSE_WAIT   = 8
   679  	BPF_TCP_LAST_ACK     = 9
   680  	BPF_TCP_CLOSING      = 10
   681  	BPF_TCP_TIME_WAIT    = 11
   682  	BPF_TCP_NEW_SYN_RECV = -1
   683  	BPF_TCP_MAX_STATES   = -2
   684  )
   685  
   686  type nwmTriplet struct {
   687  	offset uint32
   688  	length uint32
   689  	number uint32
   690  }
   691  
   692  type nwmQuadruplet struct {
   693  	offset uint32
   694  	length uint32
   695  	number uint32
   696  	match  uint32
   697  }
   698  
   699  type nwmHeader struct {
   700  	ident       uint32
   701  	length      uint32
   702  	version     uint16
   703  	nwmType     uint16
   704  	bytesNeeded uint32
   705  	options     uint32
   706  	_           [16]byte
   707  	inputDesc   nwmTriplet
   708  	outputDesc  nwmQuadruplet
   709  }
   710  
   711  type nwmFilter struct {
   712  	ident         uint32
   713  	flags         uint32
   714  	resourceName  [8]byte
   715  	resourceId    uint32
   716  	listenerId    uint32
   717  	local         [28]byte // union of sockaddr4 and sockaddr6
   718  	remote        [28]byte // union of sockaddr4 and sockaddr6
   719  	_             uint16
   720  	_             uint16
   721  	asid          uint16
   722  	_             [2]byte
   723  	tnLuName      [8]byte
   724  	tnMonGrp      uint32
   725  	tnAppl        [8]byte
   726  	applData      [40]byte
   727  	nInterface    [16]byte
   728  	dVipa         [16]byte
   729  	dVipaPfx      uint16
   730  	dVipaPort     uint16
   731  	dVipaFamily   byte
   732  	_             [3]byte
   733  	destXCF       [16]byte
   734  	destXCFPfx    uint16
   735  	destXCFFamily byte
   736  	_             [1]byte
   737  	targIP        [16]byte
   738  	targIPPfx     uint16
   739  	targIPFamily  byte
   740  	_             [1]byte
   741  	_             [20]byte
   742  }
   743  
   744  type nwmRecHeader struct {
   745  	ident  uint32
   746  	length uint32
   747  	number byte
   748  	_      [3]byte
   749  }
   750  
   751  type nwmTCPStatsEntry struct {
   752  	ident             uint64
   753  	currEstab         uint32
   754  	activeOpened      uint32
   755  	passiveOpened     uint32
   756  	connClosed        uint32
   757  	estabResets       uint32
   758  	attemptFails      uint32
   759  	passiveDrops      uint32
   760  	timeWaitReused    uint32
   761  	inSegs            uint64
   762  	predictAck        uint32
   763  	predictData       uint32
   764  	inDupAck          uint32
   765  	inBadSum          uint32
   766  	inBadLen          uint32
   767  	inShort           uint32
   768  	inDiscOldTime     uint32
   769  	inAllBeforeWin    uint32
   770  	inSomeBeforeWin   uint32
   771  	inAllAfterWin     uint32
   772  	inSomeAfterWin    uint32
   773  	inOutOfOrder      uint32
   774  	inAfterClose      uint32
   775  	inWinProbes       uint32
   776  	inWinUpdates      uint32
   777  	outWinUpdates     uint32
   778  	outSegs           uint64
   779  	outDelayAcks      uint32
   780  	outRsts           uint32
   781  	retransSegs       uint32
   782  	retransTimeouts   uint32
   783  	retransDrops      uint32
   784  	pmtuRetrans       uint32
   785  	pmtuErrors        uint32
   786  	outWinProbes      uint32
   787  	probeDrops        uint32
   788  	keepAliveProbes   uint32
   789  	keepAliveDrops    uint32
   790  	finwait2Drops     uint32
   791  	acceptCount       uint64
   792  	inBulkQSegs       uint64
   793  	inDiscards        uint64
   794  	connFloods        uint32
   795  	connStalls        uint32
   796  	cfgEphemDef       uint16
   797  	ephemInUse        uint16
   798  	ephemHiWater      uint16
   799  	flags             byte
   800  	_                 [1]byte
   801  	ephemExhaust      uint32
   802  	smcRCurrEstabLnks uint32
   803  	smcRLnkActTimeOut uint32
   804  	smcRActLnkOpened  uint32
   805  	smcRPasLnkOpened  uint32
   806  	smcRLnksClosed    uint32
   807  	smcRCurrEstab     uint32
   808  	smcRActiveOpened  uint32
   809  	smcRPassiveOpened uint32
   810  	smcRConnClosed    uint32
   811  	smcRInSegs        uint64
   812  	smcROutSegs       uint64
   813  	smcRInRsts        uint32
   814  	smcROutRsts       uint32
   815  	smcDCurrEstabLnks uint32
   816  	smcDActLnkOpened  uint32
   817  	smcDPasLnkOpened  uint32
   818  	smcDLnksClosed    uint32
   819  	smcDCurrEstab     uint32
   820  	smcDActiveOpened  uint32
   821  	smcDPassiveOpened uint32
   822  	smcDConnClosed    uint32
   823  	smcDInSegs        uint64
   824  	smcDOutSegs       uint64
   825  	smcDInRsts        uint32
   826  	smcDOutRsts       uint32
   827  }
   828  
   829  type nwmConnEntry struct {
   830  	ident             uint32
   831  	local             [28]byte // union of sockaddr4 and sockaddr6
   832  	remote            [28]byte // union of sockaddr4 and sockaddr6
   833  	startTime         [8]byte  // uint64, changed to prevent padding from being inserted
   834  	lastActivity      [8]byte  // uint64
   835  	bytesIn           [8]byte  // uint64
   836  	bytesOut          [8]byte  // uint64
   837  	inSegs            [8]byte  // uint64
   838  	outSegs           [8]byte  // uint64
   839  	state             uint16
   840  	activeOpen        byte
   841  	flag01            byte
   842  	outBuffered       uint32
   843  	inBuffered        uint32
   844  	maxSndWnd         uint32
   845  	reXmtCount        uint32
   846  	congestionWnd     uint32
   847  	ssThresh          uint32
   848  	roundTripTime     uint32
   849  	roundTripVar      uint32
   850  	sendMSS           uint32
   851  	sndWnd            uint32
   852  	rcvBufSize        uint32
   853  	sndBufSize        uint32
   854  	outOfOrderCount   uint32
   855  	lcl0WindowCount   uint32
   856  	rmt0WindowCount   uint32
   857  	dupacks           uint32
   858  	flag02            byte
   859  	sockOpt6Cont      byte
   860  	asid              uint16
   861  	resourceName      [8]byte
   862  	resourceId        uint32
   863  	subtask           uint32
   864  	sockOpt           byte
   865  	sockOpt6          byte
   866  	clusterConnFlag   byte
   867  	proto             byte
   868  	targetAppl        [8]byte
   869  	luName            [8]byte
   870  	clientUserId      [8]byte
   871  	logMode           [8]byte
   872  	timeStamp         uint32
   873  	timeStampAge      uint32
   874  	serverResourceId  uint32
   875  	intfName          [16]byte
   876  	ttlsStatPol       byte
   877  	ttlsStatConn      byte
   878  	ttlsSSLProt       uint16
   879  	ttlsNegCiph       [2]byte
   880  	ttlsSecType       byte
   881  	ttlsFIPS140Mode   byte
   882  	ttlsUserID        [8]byte
   883  	applData          [40]byte
   884  	inOldestTime      [8]byte // uint64
   885  	outOldestTime     [8]byte // uint64
   886  	tcpTrustedPartner byte
   887  	_                 [3]byte
   888  	bulkDataIntfName  [16]byte
   889  	ttlsNegCiph4      [4]byte
   890  	smcReason         uint32
   891  	lclSMCLinkId      uint32
   892  	rmtSMCLinkId      uint32
   893  	smcStatus         byte
   894  	smcFlags          byte
   895  	_                 [2]byte
   896  	rcvWnd            uint32
   897  	lclSMCBufSz       uint32
   898  	rmtSMCBufSz       uint32
   899  	ttlsSessID        [32]byte
   900  	ttlsSessIDLen     int16
   901  	_                 [1]byte
   902  	smcDStatus        byte
   903  	smcDReason        uint32
   904  }
   905  
   906  var svcNameTable [][]byte = [][]byte{
   907  	[]byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"), // svc_EZBNMIF4
   908  }
   909  
   910  const (
   911  	svc_EZBNMIF4 = 0
   912  )
   913  
   914  func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
   915  	jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40") // "*"
   916  	responseBuffer := [4096]byte{0}
   917  	var bufferAlet, reasonCode uint32 = 0, 0
   918  	var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
   919  
   920  	dsa := [18]uint64{0}
   921  	var argv [7]unsafe.Pointer
   922  	argv[0] = unsafe.Pointer(&jobname[0])
   923  	argv[1] = unsafe.Pointer(&responseBuffer[0])
   924  	argv[2] = unsafe.Pointer(&bufferAlet)
   925  	argv[3] = unsafe.Pointer(&bufferLen)
   926  	argv[4] = unsafe.Pointer(&returnValue)
   927  	argv[5] = unsafe.Pointer(&returnCode)
   928  	argv[6] = unsafe.Pointer(&reasonCode)
   929  
   930  	request := (*struct {
   931  		header nwmHeader
   932  		filter nwmFilter
   933  	})(unsafe.Pointer(&responseBuffer[0]))
   934  
   935  	EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
   936  	if EZBNMIF4 == nil {
   937  		return nil, errnoErr(EINVAL)
   938  	}
   939  
   940  	// GetGlobalStats EZBNMIF4 call
   941  	request.header.ident = nwmHeaderIdentifier
   942  	request.header.length = uint32(unsafe.Sizeof(request.header))
   943  	request.header.version = nwmCurrentVer
   944  	request.header.nwmType = nwmGlobalStatsType
   945  	request.header.options = 0x80000000
   946  
   947  	svcCall(EZBNMIF4, &argv[0], &dsa[0])
   948  
   949  	// outputDesc field is filled by EZBNMIF4 on success
   950  	if returnCode != 0 || request.header.outputDesc.offset == 0 {
   951  		return nil, errnoErr(EINVAL)
   952  	}
   953  
   954  	// Check that EZBNMIF4 returned a nwmRecHeader
   955  	recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
   956  	if recHeader.ident != nwmRecHeaderIdentifier {
   957  		return nil, errnoErr(EINVAL)
   958  	}
   959  
   960  	// Parse nwmTriplets to get offsets of returned entries
   961  	var sections []*uint64
   962  	var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
   963  	for i := uint32(0); i < uint32(recHeader.number); i++ {
   964  		offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
   965  		sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
   966  		for j := uint32(0); j < sectionDesc.number; j++ {
   967  			offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
   968  			sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
   969  		}
   970  	}
   971  
   972  	// Find nwmTCPStatsEntry in returned entries
   973  	var tcpStats *nwmTCPStatsEntry = nil
   974  	for _, ptr := range sections {
   975  		switch *ptr {
   976  		case nwmTCPStatsIdentifier:
   977  			if tcpStats != nil {
   978  				return nil, errnoErr(EINVAL)
   979  			}
   980  			tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
   981  		case nwmIPStatsIdentifier:
   982  		case nwmIPGStatsIdentifier:
   983  		case nwmUDPStatsIdentifier:
   984  		case nwmICMPGStatsEntry:
   985  		case nwmICMPTStatsEntry:
   986  		default:
   987  			return nil, errnoErr(EINVAL)
   988  		}
   989  	}
   990  	if tcpStats == nil {
   991  		return nil, errnoErr(EINVAL)
   992  	}
   993  
   994  	// GetConnectionDetail EZBNMIF4 call
   995  	responseBuffer = [4096]byte{0}
   996  	dsa = [18]uint64{0}
   997  	bufferAlet, reasonCode = 0, 0
   998  	bufferLen, returnValue, returnCode = 4096, 0, 0
   999  	nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process
  1000  	nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
  1001  	argv[0] = unsafe.Pointer(uintptr(*nameptr))
  1002  
  1003  	request.header.ident = nwmHeaderIdentifier
  1004  	request.header.length = uint32(unsafe.Sizeof(request.header))
  1005  	request.header.version = nwmCurrentVer
  1006  	request.header.nwmType = nwmTCPConnType
  1007  	request.header.options = 0x80000000
  1008  
  1009  	request.filter.ident = nwmFilterIdentifier
  1010  
  1011  	var localSockaddr RawSockaddrAny
  1012  	socklen := _Socklen(SizeofSockaddrAny)
  1013  	err := getsockname(fd, &localSockaddr, &socklen)
  1014  	if err != nil {
  1015  		return nil, errnoErr(EINVAL)
  1016  	}
  1017  	if localSockaddr.Addr.Family == AF_INET {
  1018  		localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
  1019  		localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
  1020  		localSockFilter.Family = AF_INET
  1021  		var i int
  1022  		for i = 0; i < 4; i++ {
  1023  			if localSockaddr.Addr[i] != 0 {
  1024  				break
  1025  			}
  1026  		}
  1027  		if i != 4 {
  1028  			request.filter.flags |= nwmFilterLclAddrMask
  1029  			for i = 0; i < 4; i++ {
  1030  				localSockFilter.Addr[i] = localSockaddr.Addr[i]
  1031  			}
  1032  		}
  1033  		if localSockaddr.Port != 0 {
  1034  			request.filter.flags |= nwmFilterLclPortMask
  1035  			localSockFilter.Port = localSockaddr.Port
  1036  		}
  1037  	} else if localSockaddr.Addr.Family == AF_INET6 {
  1038  		localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
  1039  		localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
  1040  		localSockFilter.Family = AF_INET6
  1041  		var i int
  1042  		for i = 0; i < 16; i++ {
  1043  			if localSockaddr.Addr[i] != 0 {
  1044  				break
  1045  			}
  1046  		}
  1047  		if i != 16 {
  1048  			request.filter.flags |= nwmFilterLclAddrMask
  1049  			for i = 0; i < 16; i++ {
  1050  				localSockFilter.Addr[i] = localSockaddr.Addr[i]
  1051  			}
  1052  		}
  1053  		if localSockaddr.Port != 0 {
  1054  			request.filter.flags |= nwmFilterLclPortMask
  1055  			localSockFilter.Port = localSockaddr.Port
  1056  		}
  1057  	}
  1058  
  1059  	svcCall(EZBNMIF4, &argv[0], &dsa[0])
  1060  
  1061  	// outputDesc field is filled by EZBNMIF4 on success
  1062  	if returnCode != 0 || request.header.outputDesc.offset == 0 {
  1063  		return nil, errnoErr(EINVAL)
  1064  	}
  1065  
  1066  	// Check that EZBNMIF4 returned a nwmConnEntry
  1067  	conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
  1068  	if conn.ident != nwmTCPConnIdentifier {
  1069  		return nil, errnoErr(EINVAL)
  1070  	}
  1071  
  1072  	// Copy data from the returned data structures into tcpInfo
  1073  	// Stats from nwmConnEntry are specific to that connection.
  1074  	// Stats from nwmTCPStatsEntry are global (to the interface?)
  1075  	// Fields may not be an exact match. Some fields have no equivalent.
  1076  	var tcpinfo TCPInfo
  1077  	tcpinfo.State = uint8(conn.state)
  1078  	tcpinfo.Ca_state = 0 // dummy
  1079  	tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
  1080  	tcpinfo.Probes = uint8(tcpStats.outWinProbes)
  1081  	tcpinfo.Backoff = 0 // dummy
  1082  	tcpinfo.Options = 0 // dummy
  1083  	tcpinfo.Rto = tcpStats.retransTimeouts
  1084  	tcpinfo.Ato = tcpStats.outDelayAcks
  1085  	tcpinfo.Snd_mss = conn.sendMSS
  1086  	tcpinfo.Rcv_mss = conn.sendMSS // dummy
  1087  	tcpinfo.Unacked = 0            // dummy
  1088  	tcpinfo.Sacked = 0             // dummy
  1089  	tcpinfo.Lost = 0               // dummy
  1090  	tcpinfo.Retrans = conn.reXmtCount
  1091  	tcpinfo.Fackets = 0 // dummy
  1092  	tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
  1093  	tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
  1094  	tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  1095  	tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  1096  	tcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate
  1097  	tcpinfo.Rcv_ssthresh = conn.ssThresh
  1098  	tcpinfo.Rtt = conn.roundTripTime
  1099  	tcpinfo.Rttvar = conn.roundTripVar
  1100  	tcpinfo.Snd_ssthresh = conn.ssThresh // dummy
  1101  	tcpinfo.Snd_cwnd = conn.congestionWnd
  1102  	tcpinfo.Advmss = conn.sendMSS        // dummy
  1103  	tcpinfo.Reordering = 0               // dummy
  1104  	tcpinfo.Rcv_rtt = conn.roundTripTime // dummy
  1105  	tcpinfo.Rcv_space = conn.sendMSS     // dummy
  1106  	tcpinfo.Total_retrans = conn.reXmtCount
  1107  
  1108  	svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
  1109  
  1110  	return &tcpinfo, nil
  1111  }
  1112  
  1113  // GetsockoptString returns the string value of the socket option opt for the
  1114  // socket associated with fd at the given socket level.
  1115  func GetsockoptString(fd, level, opt int) (string, error) {
  1116  	buf := make([]byte, 256)
  1117  	vallen := _Socklen(len(buf))
  1118  	err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
  1119  	if err != nil {
  1120  		return "", err
  1121  	}
  1122  
  1123  	return string(buf[:vallen-1]), nil
  1124  }
  1125  
  1126  func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  1127  	var msg Msghdr
  1128  	var rsa RawSockaddrAny
  1129  	msg.Name = (*byte)(unsafe.Pointer(&rsa))
  1130  	msg.Namelen = SizeofSockaddrAny
  1131  	var iov Iovec
  1132  	if len(p) > 0 {
  1133  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1134  		iov.SetLen(len(p))
  1135  	}
  1136  	var dummy byte
  1137  	if len(oob) > 0 {
  1138  		// receive at least one normal byte
  1139  		if len(p) == 0 {
  1140  			iov.Base = &dummy
  1141  			iov.SetLen(1)
  1142  		}
  1143  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1144  		msg.SetControllen(len(oob))
  1145  	}
  1146  	msg.Iov = &iov
  1147  	msg.Iovlen = 1
  1148  	if n, err = recvmsg(fd, &msg, flags); err != nil {
  1149  		return
  1150  	}
  1151  	oobn = int(msg.Controllen)
  1152  	recvflags = int(msg.Flags)
  1153  	// source address is only specified if the socket is unconnected
  1154  	if rsa.Addr.Family != AF_UNSPEC {
  1155  		// TODO(neeilan): Remove 0 arg added to get this compiling on z/OS
  1156  		from, err = anyToSockaddr(0, &rsa)
  1157  	}
  1158  	return
  1159  }
  1160  
  1161  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
  1162  	_, err = SendmsgN(fd, p, oob, to, flags)
  1163  	return
  1164  }
  1165  
  1166  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
  1167  	var ptr unsafe.Pointer
  1168  	var salen _Socklen
  1169  	if to != nil {
  1170  		var err error
  1171  		ptr, salen, err = to.sockaddr()
  1172  		if err != nil {
  1173  			return 0, err
  1174  		}
  1175  	}
  1176  	var msg Msghdr
  1177  	msg.Name = (*byte)(unsafe.Pointer(ptr))
  1178  	msg.Namelen = int32(salen)
  1179  	var iov Iovec
  1180  	if len(p) > 0 {
  1181  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1182  		iov.SetLen(len(p))
  1183  	}
  1184  	var dummy byte
  1185  	if len(oob) > 0 {
  1186  		// send at least one normal byte
  1187  		if len(p) == 0 {
  1188  			iov.Base = &dummy
  1189  			iov.SetLen(1)
  1190  		}
  1191  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1192  		msg.SetControllen(len(oob))
  1193  	}
  1194  	msg.Iov = &iov
  1195  	msg.Iovlen = 1
  1196  	if n, err = sendmsg(fd, &msg, flags); err != nil {
  1197  		return 0, err
  1198  	}
  1199  	if len(oob) > 0 && len(p) == 0 {
  1200  		n = 0
  1201  	}
  1202  	return n, nil
  1203  }
  1204  
  1205  func Opendir(name string) (uintptr, error) {
  1206  	p, err := BytePtrFromString(name)
  1207  	if err != nil {
  1208  		return 0, err
  1209  	}
  1210  	dir, _, e := syscall_syscall(SYS___OPENDIR_A, uintptr(unsafe.Pointer(p)), 0, 0)
  1211  	runtime.KeepAlive(unsafe.Pointer(p))
  1212  	if e != 0 {
  1213  		err = errnoErr(e)
  1214  	}
  1215  	return dir, err
  1216  }
  1217  
  1218  // clearsyscall.Errno resets the errno value to 0.
  1219  func clearErrno()
  1220  
  1221  func Readdir(dir uintptr) (*Dirent, error) {
  1222  	var ent Dirent
  1223  	var res uintptr
  1224  	// __readdir_r_a returns errno at the end of the directory stream, rather than 0.
  1225  	// Therefore to avoid false positives we clear errno before calling it.
  1226  
  1227  	// TODO(neeilan): Commented this out to get sys/unix compiling on z/OS. Uncomment and fix. Error: "undefined: clearsyscall"
  1228  	//clearsyscall.Errno() // TODO(mundaym): check pre-emption rules.
  1229  
  1230  	e, _, _ := syscall_syscall(SYS___READDIR_R_A, dir, uintptr(unsafe.Pointer(&ent)), uintptr(unsafe.Pointer(&res)))
  1231  	var err error
  1232  	if e != 0 {
  1233  		err = errnoErr(Errno(e))
  1234  	}
  1235  	if res == 0 {
  1236  		return nil, err
  1237  	}
  1238  	return &ent, err
  1239  }
  1240  
  1241  func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
  1242  	r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
  1243  	if int64(r0) == -1 {
  1244  		err = errnoErr(Errno(e1))
  1245  	}
  1246  	return
  1247  }
  1248  
  1249  func Closedir(dir uintptr) error {
  1250  	_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
  1251  	if e != 0 {
  1252  		return errnoErr(e)
  1253  	}
  1254  	return nil
  1255  }
  1256  
  1257  func Seekdir(dir uintptr, pos int) {
  1258  	_, _, _ = syscall_syscall(SYS_SEEKDIR, dir, uintptr(pos), 0)
  1259  }
  1260  
  1261  func Telldir(dir uintptr) (int, error) {
  1262  	p, _, e := syscall_syscall(SYS_TELLDIR, dir, 0, 0)
  1263  	pos := int(p)
  1264  	if pos == -1 {
  1265  		return pos, errnoErr(e)
  1266  	}
  1267  	return pos, nil
  1268  }
  1269  
  1270  // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
  1271  func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
  1272  	// struct flock is packed on z/OS. We can't emulate that in Go so
  1273  	// instead we pack it here.
  1274  	var flock [24]byte
  1275  	*(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
  1276  	*(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
  1277  	*(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
  1278  	*(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
  1279  	*(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
  1280  	_, _, errno := syscall_syscall(SYS_FCNTL, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
  1281  	lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
  1282  	lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
  1283  	lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
  1284  	lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
  1285  	lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
  1286  	if errno == 0 {
  1287  		return nil
  1288  	}
  1289  	return errno
  1290  }
  1291  
  1292  func Flock(fd int, how int) error {
  1293  
  1294  	var flock_type int16
  1295  	var fcntl_cmd int
  1296  
  1297  	switch how {
  1298  	case LOCK_SH | LOCK_NB:
  1299  		flock_type = F_RDLCK
  1300  		fcntl_cmd = F_SETLK
  1301  	case LOCK_EX | LOCK_NB:
  1302  		flock_type = F_WRLCK
  1303  		fcntl_cmd = F_SETLK
  1304  	case LOCK_EX:
  1305  		flock_type = F_WRLCK
  1306  		fcntl_cmd = F_SETLKW
  1307  	case LOCK_UN:
  1308  		flock_type = F_UNLCK
  1309  		fcntl_cmd = F_SETLKW
  1310  	default:
  1311  	}
  1312  
  1313  	flock := Flock_t{
  1314  		Type:   int16(flock_type),
  1315  		Whence: int16(0),
  1316  		Start:  int64(0),
  1317  		Len:    int64(0),
  1318  		Pid:    int32(Getppid()),
  1319  	}
  1320  
  1321  	err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
  1322  	return err
  1323  }
  1324  
  1325  func Mlock(b []byte) (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 Mlock2(b []byte, flags int) (err error) {
  1334  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
  1335  	if e1 != 0 {
  1336  		err = errnoErr(e1)
  1337  	}
  1338  	return
  1339  }
  1340  
  1341  func Mlockall(flags int) (err error) {
  1342  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
  1343  	if e1 != 0 {
  1344  		err = errnoErr(e1)
  1345  	}
  1346  	return
  1347  }
  1348  
  1349  func Munlock(b []byte) (err error) {
  1350  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
  1351  	if e1 != 0 {
  1352  		err = errnoErr(e1)
  1353  	}
  1354  	return
  1355  }
  1356  
  1357  func Munlockall() (err error) {
  1358  	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
  1359  	if e1 != 0 {
  1360  		err = errnoErr(e1)
  1361  	}
  1362  	return
  1363  }
  1364  
  1365  func ClockGettime(clockid int32, ts *Timespec) error {
  1366  
  1367  	var ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise
  1368  	var nsec_per_sec int64 = 1000000000
  1369  
  1370  	if ts == nil {
  1371  		return EFAULT
  1372  	}
  1373  	if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
  1374  		var nanotime int64 = runtime.Nanotime1()
  1375  		ts.Sec = nanotime / nsec_per_sec
  1376  		ts.Nsec = nanotime % nsec_per_sec
  1377  	} else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
  1378  		var tm Tms
  1379  		_, err := Times(&tm)
  1380  		if err != nil {
  1381  			return EFAULT
  1382  		}
  1383  		ts.Sec = int64(tm.Utime / ticks_per_sec)
  1384  		ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
  1385  	} else {
  1386  		return EINVAL
  1387  	}
  1388  	return nil
  1389  }
  1390  
  1391  func Statfs(path string, stat *Statfs_t) (err error) {
  1392  	fd, err := open(path, O_RDONLY, 0)
  1393  	defer Close(fd)
  1394  	if err != nil {
  1395  		return err
  1396  	}
  1397  	return Fstatfs(fd, stat)
  1398  }
  1399  
  1400  var (
  1401  	Stdin  = 0
  1402  	Stdout = 1
  1403  	Stderr = 2
  1404  )
  1405  
  1406  // Do the interface allocations only once for common
  1407  // Errno values.
  1408  var (
  1409  	errEAGAIN error = syscall.EAGAIN
  1410  	errEINVAL error = syscall.EINVAL
  1411  	errENOENT error = syscall.ENOENT
  1412  )
  1413  
  1414  var (
  1415  	signalNameMapOnce sync.Once
  1416  	signalNameMap     map[string]syscall.Signal
  1417  )
  1418  
  1419  // errnoErr returns common boxed Errno values, to prevent
  1420  // allocations at runtime.
  1421  func errnoErr(e Errno) error {
  1422  	switch e {
  1423  	case 0:
  1424  		return nil
  1425  	case EAGAIN:
  1426  		return errEAGAIN
  1427  	case EINVAL:
  1428  		return errEINVAL
  1429  	case ENOENT:
  1430  		return errENOENT
  1431  	}
  1432  	return e
  1433  }
  1434  
  1435  // ErrnoName returns the error name for error number e.
  1436  func ErrnoName(e Errno) string {
  1437  	i := sort.Search(len(errorList), func(i int) bool {
  1438  		return errorList[i].num >= e
  1439  	})
  1440  	if i < len(errorList) && errorList[i].num == e {
  1441  		return errorList[i].name
  1442  	}
  1443  	return ""
  1444  }
  1445  
  1446  // SignalName returns the signal name for signal number s.
  1447  func SignalName(s syscall.Signal) string {
  1448  	i := sort.Search(len(signalList), func(i int) bool {
  1449  		return signalList[i].num >= s
  1450  	})
  1451  	if i < len(signalList) && signalList[i].num == s {
  1452  		return signalList[i].name
  1453  	}
  1454  	return ""
  1455  }
  1456  
  1457  // SignalNum returns the syscall.Signal for signal named s,
  1458  // or 0 if a signal with such name is not found.
  1459  // The signal name should start with "SIG".
  1460  func SignalNum(s string) syscall.Signal {
  1461  	signalNameMapOnce.Do(func() {
  1462  		signalNameMap = make(map[string]syscall.Signal, len(signalList))
  1463  		for _, signal := range signalList {
  1464  			signalNameMap[signal.name] = signal.num
  1465  		}
  1466  	})
  1467  	return signalNameMap[s]
  1468  }
  1469  
  1470  // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
  1471  func clen(n []byte) int {
  1472  	i := bytes.IndexByte(n, 0)
  1473  	if i == -1 {
  1474  		i = len(n)
  1475  	}
  1476  	return i
  1477  }
  1478  
  1479  // Mmap manager, for use by operating system-specific implementations.
  1480  
  1481  type mmapper struct {
  1482  	sync.Mutex
  1483  	active map[*byte][]byte // active mappings; key is last byte in mapping
  1484  	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
  1485  	munmap func(addr uintptr, length uintptr) error
  1486  }
  1487  
  1488  func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  1489  	if length <= 0 {
  1490  		return nil, EINVAL
  1491  	}
  1492  
  1493  	// Map the requested memory.
  1494  	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
  1495  	if errno != nil {
  1496  		return nil, errno
  1497  	}
  1498  
  1499  	// Slice memory layout
  1500  	var sl = struct {
  1501  		addr uintptr
  1502  		len  int
  1503  		cap  int
  1504  	}{addr, length, length}
  1505  
  1506  	// Use unsafe to turn sl into a []byte.
  1507  	b := *(*[]byte)(unsafe.Pointer(&sl))
  1508  
  1509  	// Register mapping in m and return it.
  1510  	p := &b[cap(b)-1]
  1511  	m.Lock()
  1512  	defer m.Unlock()
  1513  	m.active[p] = b
  1514  	return b, nil
  1515  }
  1516  
  1517  func (m *mmapper) Munmap(data []byte) (err error) {
  1518  	if len(data) == 0 || len(data) != cap(data) {
  1519  		return EINVAL
  1520  	}
  1521  
  1522  	// Find the base of the mapping.
  1523  	p := &data[cap(data)-1]
  1524  	m.Lock()
  1525  	defer m.Unlock()
  1526  	b := m.active[p]
  1527  	if b == nil || &b[0] != &data[0] {
  1528  		return EINVAL
  1529  	}
  1530  
  1531  	// Unmap the memory and update m.
  1532  	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
  1533  		return errno
  1534  	}
  1535  	delete(m.active, p)
  1536  	return nil
  1537  }
  1538  
  1539  func Read(fd int, p []byte) (n int, err error) {
  1540  	n, err = read(fd, p)
  1541  	if raceenabled {
  1542  		if n > 0 {
  1543  			raceWriteRange(unsafe.Pointer(&p[0]), n)
  1544  		}
  1545  		if err == nil {
  1546  			raceAcquire(unsafe.Pointer(&ioSync))
  1547  		}
  1548  	}
  1549  	return
  1550  }
  1551  
  1552  func Write(fd int, p []byte) (n int, err error) {
  1553  	if raceenabled {
  1554  		raceReleaseMerge(unsafe.Pointer(&ioSync))
  1555  	}
  1556  	n, err = write(fd, p)
  1557  	if raceenabled && n > 0 {
  1558  		raceReadRange(unsafe.Pointer(&p[0]), n)
  1559  	}
  1560  	return
  1561  }
  1562  
  1563  // For testing: clients can set this flag to force
  1564  // creation of IPv6 sockets to return EAFNOSUPPORT.
  1565  var SocketDisableIPv6 bool
  1566  
  1567  // Sockaddr represents a socket address.
  1568  type Sockaddr interface {
  1569  	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
  1570  }
  1571  
  1572  // SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
  1573  type SockaddrInet4 struct {
  1574  	Port int
  1575  	Addr [4]byte
  1576  	raw  RawSockaddrInet4
  1577  }
  1578  
  1579  // SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
  1580  type SockaddrInet6 struct {
  1581  	Port   int
  1582  	ZoneId uint32
  1583  	Addr   [16]byte
  1584  	raw    RawSockaddrInet6
  1585  }
  1586  
  1587  // SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
  1588  type SockaddrUnix struct {
  1589  	Name string
  1590  	raw  RawSockaddrUnix
  1591  }
  1592  
  1593  func Bind(fd int, sa Sockaddr) (err error) {
  1594  	ptr, n, err := sa.sockaddr()
  1595  	if err != nil {
  1596  		return err
  1597  	}
  1598  	return bind(fd, ptr, n)
  1599  }
  1600  
  1601  func Connect(fd int, sa Sockaddr) (err error) {
  1602  	ptr, n, err := sa.sockaddr()
  1603  	if err != nil {
  1604  		return err
  1605  	}
  1606  	return connect(fd, ptr, n)
  1607  }
  1608  
  1609  func Getpeername(fd int) (sa Sockaddr, err error) {
  1610  	var rsa RawSockaddrAny
  1611  	var len _Socklen = SizeofSockaddrAny
  1612  	if err = getpeername(fd, &rsa, &len); err != nil {
  1613  		return
  1614  	}
  1615  	return anyToSockaddr(fd, &rsa)
  1616  }
  1617  
  1618  func GetsockoptByte(fd, level, opt int) (value byte, err error) {
  1619  	var n byte
  1620  	vallen := _Socklen(1)
  1621  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1622  	return n, err
  1623  }
  1624  
  1625  func GetsockoptInt(fd, level, opt int) (value int, err error) {
  1626  	var n int32
  1627  	vallen := _Socklen(4)
  1628  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1629  	return int(n), err
  1630  }
  1631  
  1632  func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
  1633  	vallen := _Socklen(4)
  1634  	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
  1635  	return value, err
  1636  }
  1637  
  1638  func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
  1639  	var value IPMreq
  1640  	vallen := _Socklen(SizeofIPMreq)
  1641  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1642  	return &value, err
  1643  }
  1644  
  1645  func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
  1646  	var value IPv6Mreq
  1647  	vallen := _Socklen(SizeofIPv6Mreq)
  1648  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1649  	return &value, err
  1650  }
  1651  
  1652  func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
  1653  	var value IPv6MTUInfo
  1654  	vallen := _Socklen(SizeofIPv6MTUInfo)
  1655  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1656  	return &value, err
  1657  }
  1658  
  1659  func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
  1660  	var value ICMPv6Filter
  1661  	vallen := _Socklen(SizeofICMPv6Filter)
  1662  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  1663  	return &value, err
  1664  }
  1665  
  1666  func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
  1667  	var linger Linger
  1668  	vallen := _Socklen(SizeofLinger)
  1669  	err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
  1670  	return &linger, err
  1671  }
  1672  
  1673  func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
  1674  	var tv Timeval
  1675  	vallen := _Socklen(unsafe.Sizeof(tv))
  1676  	err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
  1677  	return &tv, err
  1678  }
  1679  
  1680  func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
  1681  	var n uint64
  1682  	vallen := _Socklen(8)
  1683  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  1684  	return n, err
  1685  }
  1686  
  1687  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
  1688  	var rsa RawSockaddrAny
  1689  	var len _Socklen = SizeofSockaddrAny
  1690  	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
  1691  		return
  1692  	}
  1693  	if rsa.Addr.Family != AF_UNSPEC {
  1694  		from, err = anyToSockaddr(fd, &rsa)
  1695  	}
  1696  	return
  1697  }
  1698  
  1699  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
  1700  	ptr, n, err := to.sockaddr()
  1701  	if err != nil {
  1702  		return err
  1703  	}
  1704  	return sendto(fd, p, flags, ptr, n)
  1705  }
  1706  
  1707  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
  1708  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
  1709  }
  1710  
  1711  func SetsockoptInt(fd, level, opt int, value int) (err error) {
  1712  	var n = int32(value)
  1713  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
  1714  }
  1715  
  1716  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
  1717  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
  1718  }
  1719  
  1720  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
  1721  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
  1722  }
  1723  
  1724  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
  1725  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
  1726  }
  1727  
  1728  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
  1729  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
  1730  }
  1731  
  1732  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
  1733  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
  1734  }
  1735  
  1736  func SetsockoptString(fd, level, opt int, s string) (err error) {
  1737  	var p unsafe.Pointer
  1738  	if len(s) > 0 {
  1739  		p = unsafe.Pointer(&[]byte(s)[0])
  1740  	}
  1741  	return setsockopt(fd, level, opt, p, uintptr(len(s)))
  1742  }
  1743  
  1744  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
  1745  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
  1746  }
  1747  
  1748  func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
  1749  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
  1750  }
  1751  
  1752  func Socket(domain, typ, proto int) (fd int, err error) {
  1753  	if domain == AF_INET6 && SocketDisableIPv6 {
  1754  		return -1, EAFNOSUPPORT
  1755  	}
  1756  	fd, err = socket(domain, typ, proto)
  1757  	return
  1758  }
  1759  
  1760  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
  1761  	var fdx [2]int32
  1762  	err = socketpair(domain, typ, proto, &fdx)
  1763  	if err == nil {
  1764  		fd[0] = int(fdx[0])
  1765  		fd[1] = int(fdx[1])
  1766  	}
  1767  	return
  1768  }
  1769  
  1770  var ioSync int64
  1771  
  1772  func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
  1773  
  1774  func SetNonblock(fd int, nonblocking bool) (err error) {
  1775  	flag, err := fcntl(fd, F_GETFL, 0)
  1776  	if err != nil {
  1777  		return err
  1778  	}
  1779  	if nonblocking {
  1780  		flag |= O_NONBLOCK
  1781  	} else {
  1782  		flag &= ^O_NONBLOCK
  1783  	}
  1784  	_, err = fcntl(fd, F_SETFL, flag)
  1785  	return err
  1786  }
  1787  
  1788  // Exec calls execve(2), which replaces the calling executable in the process
  1789  // tree. argv0 should be the full path to an executable ("/bin/ls") and the
  1790  // executable name should also be the first argument in argv (["ls", "-l"]).
  1791  // envv are the environment variables that should be passed to the new
  1792  // process (["USER=go", "PWD=/tmp"]).
  1793  func Exec(argv0 string, argv []string, envv []string) error {
  1794  	return syscall.Exec(argv0, argv, envv)
  1795  }
  1796  
  1797  func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  1798  	if needspace := 8 - len(fstype); needspace <= 0 {
  1799  		fstype = fstype[:8]
  1800  	} else {
  1801  		fstype += "        "[:needspace]
  1802  	}
  1803  	return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
  1804  }
  1805  
  1806  func Unmount(name string, mtm int) (err error) {
  1807  	// mountpoint is always a full path and starts with a '/'
  1808  	// check if input string is not a mountpoint but a filesystem name
  1809  	if name[0] != '/' {
  1810  		return unmount(name, mtm)
  1811  	}
  1812  	// treat name as mountpoint
  1813  	b2s := func(arr []byte) string {
  1814  		nulli := bytes.IndexByte(arr, 0)
  1815  		if nulli == -1 {
  1816  			return string(arr)
  1817  		} else {
  1818  			return string(arr[:nulli])
  1819  		}
  1820  	}
  1821  	var buffer struct {
  1822  		header W_Mnth
  1823  		fsinfo [64]W_Mntent
  1824  	}
  1825  	fsCount, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
  1826  	if err != nil {
  1827  		return err
  1828  	}
  1829  	if fsCount == 0 {
  1830  		return EINVAL
  1831  	}
  1832  	for i := 0; i < fsCount; i++ {
  1833  		if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
  1834  			err = unmount(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
  1835  			break
  1836  		}
  1837  	}
  1838  	return err
  1839  }
  1840  
  1841  func fdToPath(dirfd int) (path string, err error) {
  1842  	var buffer [1024]byte
  1843  	// w_ctrl()
  1844  	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
  1845  		[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
  1846  	if ret == 0 {
  1847  		zb := bytes.IndexByte(buffer[:], 0)
  1848  		if zb == -1 {
  1849  			zb = len(buffer)
  1850  		}
  1851  		// __e2a_l()
  1852  		runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
  1853  			[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
  1854  		return string(buffer[:zb]), nil
  1855  	}
  1856  	// __errno()
  1857  	errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
  1858  		[]uintptr{}))))
  1859  	// __errno2()
  1860  	errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
  1861  		[]uintptr{}))
  1862  	// strerror_r()
  1863  	ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
  1864  		[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
  1865  	if ret == 0 {
  1866  		zb := bytes.IndexByte(buffer[:], 0)
  1867  		if zb == -1 {
  1868  			zb = len(buffer)
  1869  		}
  1870  		return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
  1871  	} else {
  1872  		return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
  1873  	}
  1874  }
  1875  
  1876  func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
  1877  	var d Dirent
  1878  
  1879  	d.Ino = uint64(dirent.Ino)
  1880  	offset, err := Telldir(dir)
  1881  	if err != nil {
  1882  		return d, err
  1883  	}
  1884  
  1885  	d.Off = int64(offset)
  1886  	s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
  1887  	copy(d.Name[:], s)
  1888  
  1889  	d.Reclen = uint16(24 + len(d.NameString()))
  1890  	var st Stat_t
  1891  	path = path + "/" + s
  1892  	err = Lstat(path, &st)
  1893  	if err != nil {
  1894  		return d, err
  1895  	}
  1896  
  1897  	d.Type = uint8(st.Mode >> 24)
  1898  	return d, err
  1899  }
  1900  
  1901  func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
  1902  	// Simulation of Getdirentries port from the Darwin implementation.
  1903  	// COMMENTS FROM DARWIN:
  1904  	// It's not the full required semantics, but should handle the case
  1905  	// of calling Getdirentries or ReadDirent repeatedly.
  1906  	// It won't handle assigning the results of lseek to *basep, or handle
  1907  	// the directory being edited underfoot.
  1908  
  1909  	skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
  1910  	if err != nil {
  1911  		return 0, err
  1912  	}
  1913  
  1914  	// Get path from fd to avoid unavailable call (fdopendir)
  1915  	path, err := fdToPath(fd)
  1916  	if err != nil {
  1917  		return 0, err
  1918  	}
  1919  	d, err := Opendir(path)
  1920  	if err != nil {
  1921  		return 0, err
  1922  	}
  1923  	defer Closedir(d)
  1924  
  1925  	var cnt int64
  1926  	for {
  1927  		var entryLE direntLE
  1928  		var entrypLE *direntLE
  1929  		e := readdir_r(d, &entryLE, &entrypLE)
  1930  		if e != nil {
  1931  			return n, e
  1932  		}
  1933  		if entrypLE == nil {
  1934  			break
  1935  		}
  1936  		if skip > 0 {
  1937  			skip--
  1938  			cnt++
  1939  			continue
  1940  		}
  1941  
  1942  		// Dirent on zos has a different structure
  1943  		entry, e := direntLeToDirentUnix(&entryLE, d, path)
  1944  		if e != nil {
  1945  			return n, e
  1946  		}
  1947  
  1948  		reclen := int(entry.Reclen)
  1949  		if reclen > len(buf) {
  1950  			// Not enough room. Return for now.
  1951  			// The counter will let us know where we should start up again.
  1952  			// Note: this strategy for suspending in the middle and
  1953  			// restarting is O(n^2) in the length of the directory. Oh well.
  1954  			break
  1955  		}
  1956  
  1957  		// Copy entry into return buffer.
  1958  		s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
  1959  		copy(buf, s)
  1960  
  1961  		buf = buf[reclen:]
  1962  		n += reclen
  1963  		cnt++
  1964  	}
  1965  	// Set the seek offset of the input fd to record
  1966  	// how many files we've already returned.
  1967  	_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
  1968  	if err != nil {
  1969  		return n, err
  1970  	}
  1971  
  1972  	return n, nil
  1973  }
  1974  
  1975  func ReadDirent(fd int, buf []byte) (n int, err error) {
  1976  	var base = (*uintptr)(unsafe.Pointer(new(uint64)))
  1977  	return Getdirentries(fd, buf, base)
  1978  }
  1979  
  1980  func direntIno(buf []byte) (uint64, bool) {
  1981  	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
  1982  }
  1983  
  1984  func direntReclen(buf []byte) (uint64, bool) {
  1985  	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
  1986  }
  1987  
  1988  func direntNamlen(buf []byte) (uint64, bool) {
  1989  	reclen, ok := direntReclen(buf)
  1990  	if !ok {
  1991  		return 0, false
  1992  	}
  1993  	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
  1994  }