github.com/etecs-ru/go-sys-wineventlog@v0.0.0-20210227233244-4c3abb794018/unix/syscall_zos_s390x.go (about)

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