Source file src/cmd/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go

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

View as plain text