syscall_zos_s390x.go raw

   1  // Copyright 2020 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  //go:build zos && s390x
   6  
   7  // Many of the following syscalls are not available on all versions of z/OS.
   8  // Some missing calls have legacy implementations/simulations but others
   9  // will be missing completely. To achieve consistent failing behaviour on
  10  // legacy systems, we first test the function pointer via a safeloading
  11  // mechanism to see if the function exists on a given system. Then execution
  12  // is branched to either continue the function call, or return an error.
  13  
  14  package unix
  15  
  16  import (
  17  	"bytes"
  18  	"fmt"
  19  	"os"
  20  	"reflect"
  21  	"regexp"
  22  	"runtime"
  23  	"sort"
  24  	"strings"
  25  	"sync"
  26  	"syscall"
  27  	"unsafe"
  28  )
  29  
  30  //go:noescape
  31  func initZosLibVec()
  32  
  33  //go:noescape
  34  func GetZosLibVec() uintptr
  35  
  36  func init() {
  37  	initZosLibVec()
  38  	r0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte("__ZOS_XSYSTRACE\x00"))[0])))
  39  	if r0 != 0 {
  40  		n, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)
  41  		ZosTraceLevel = int(n)
  42  		r0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte("__ZOS_XSYSTRACEFD\x00"))[0])))
  43  		if r0 != 0 {
  44  			fd, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)
  45  			f := os.NewFile(fd, "zostracefile")
  46  			if f != nil {
  47  				ZosTracefile = f
  48  			}
  49  		}
  50  
  51  	}
  52  }
  53  
  54  //go:noescape
  55  func CallLeFuncWithErr(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)
  56  
  57  //go:noescape
  58  func CallLeFuncWithPtrReturn(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)
  59  
  60  // -------------------------------
  61  // pointer validity test
  62  // good pointer returns 0
  63  // bad pointer returns 1
  64  //
  65  //go:nosplit
  66  func ptrtest(uintptr) uint64
  67  
  68  // Load memory at ptr location with error handling if the location is invalid
  69  //
  70  //go:noescape
  71  func safeload(ptr uintptr) (value uintptr, error uintptr)
  72  
  73  const (
  74  	entrypointLocationOffset = 8 // From function descriptor
  75  
  76  	xplinkEyecatcher   = 0x00c300c500c500f1 // ".C.E.E.1"
  77  	eyecatcherOffset   = 16                 // From function entrypoint (negative)
  78  	ppa1LocationOffset = 8                  // From function entrypoint (negative)
  79  
  80  	nameLenOffset = 0x14 // From PPA1 start
  81  	nameOffset    = 0x16 // From PPA1 start
  82  )
  83  
  84  func getPpaOffset(funcptr uintptr) int64 {
  85  	entrypoint, err := safeload(funcptr + entrypointLocationOffset)
  86  	if err != 0 {
  87  		return -1
  88  	}
  89  
  90  	// XPLink functions have ".C.E.E.1" as the first 8 bytes (EBCDIC)
  91  	val, err := safeload(entrypoint - eyecatcherOffset)
  92  	if err != 0 {
  93  		return -1
  94  	}
  95  	if val != xplinkEyecatcher {
  96  		return -1
  97  	}
  98  
  99  	ppaoff, err := safeload(entrypoint - ppa1LocationOffset)
 100  	if err != 0 {
 101  		return -1
 102  	}
 103  
 104  	ppaoff >>= 32
 105  	return int64(ppaoff)
 106  }
 107  
 108  //-------------------------------
 109  // function descriptor pointer validity test
 110  // good pointer returns 0
 111  // bad pointer returns 1
 112  
 113  // TODO: currently mksyscall_zos_s390x.go generate empty string for funcName
 114  // have correct funcName pass to the funcptrtest function
 115  func funcptrtest(funcptr uintptr, funcName string) uint64 {
 116  	entrypoint, err := safeload(funcptr + entrypointLocationOffset)
 117  	if err != 0 {
 118  		return 1
 119  	}
 120  
 121  	ppaoff := getPpaOffset(funcptr)
 122  	if ppaoff == -1 {
 123  		return 1
 124  	}
 125  
 126  	// PPA1 offset value is from the start of the entire function block, not the entrypoint
 127  	ppa1 := (entrypoint - eyecatcherOffset) + uintptr(ppaoff)
 128  
 129  	nameLen, err := safeload(ppa1 + nameLenOffset)
 130  	if err != 0 {
 131  		return 1
 132  	}
 133  
 134  	nameLen >>= 48
 135  	if nameLen > 128 {
 136  		return 1
 137  	}
 138  
 139  	// no function name input to argument end here
 140  	if funcName == "" {
 141  		return 0
 142  	}
 143  
 144  	var funcname [128]byte
 145  	for i := 0; i < int(nameLen); i += 8 {
 146  		v, err := safeload(ppa1 + nameOffset + uintptr(i))
 147  		if err != 0 {
 148  			return 1
 149  		}
 150  		funcname[i] = byte(v >> 56)
 151  		funcname[i+1] = byte(v >> 48)
 152  		funcname[i+2] = byte(v >> 40)
 153  		funcname[i+3] = byte(v >> 32)
 154  		funcname[i+4] = byte(v >> 24)
 155  		funcname[i+5] = byte(v >> 16)
 156  		funcname[i+6] = byte(v >> 8)
 157  		funcname[i+7] = byte(v)
 158  	}
 159  
 160  	runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, // __e2a_l
 161  		[]uintptr{uintptr(unsafe.Pointer(&funcname[0])), nameLen})
 162  
 163  	name := string(funcname[:nameLen])
 164  	if name != funcName {
 165  		return 1
 166  	}
 167  
 168  	return 0
 169  }
 170  
 171  // For detection of capabilities on a system.
 172  // Is function descriptor f a valid function?
 173  func isValidLeFunc(f uintptr) error {
 174  	ret := funcptrtest(f, "")
 175  	if ret != 0 {
 176  		return fmt.Errorf("Bad pointer, not an LE function ")
 177  	}
 178  	return nil
 179  }
 180  
 181  // Retrieve function name from descriptor
 182  func getLeFuncName(f uintptr) (string, error) {
 183  	// assume it has been checked, only check ppa1 validity here
 184  	entry := ((*[2]uintptr)(unsafe.Pointer(f)))[1]
 185  	preamp := ((*[4]uint32)(unsafe.Pointer(entry - eyecatcherOffset)))
 186  
 187  	offsetPpa1 := preamp[2]
 188  	if offsetPpa1 > 0x0ffff {
 189  		return "", fmt.Errorf("PPA1 offset seems too big 0x%x\n", offsetPpa1)
 190  	}
 191  
 192  	ppa1 := uintptr(unsafe.Pointer(preamp)) + uintptr(offsetPpa1)
 193  	res := ptrtest(ppa1)
 194  	if res != 0 {
 195  		return "", fmt.Errorf("PPA1 address not valid")
 196  	}
 197  
 198  	size := *(*uint16)(unsafe.Pointer(ppa1 + nameLenOffset))
 199  	if size > 128 {
 200  		return "", fmt.Errorf("Function name seems too long, length=%d\n", size)
 201  	}
 202  
 203  	var name [128]byte
 204  	funcname := (*[128]byte)(unsafe.Pointer(ppa1 + nameOffset))
 205  	copy(name[0:size], funcname[0:size])
 206  
 207  	runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, // __e2a_l
 208  		[]uintptr{uintptr(unsafe.Pointer(&name[0])), uintptr(size)})
 209  
 210  	return string(name[:size]), nil
 211  }
 212  
 213  // Check z/OS version
 214  func zosLeVersion() (version, release uint32) {
 215  	p1 := (*(*uintptr)(unsafe.Pointer(uintptr(1208)))) >> 32
 216  	p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 88)))
 217  	p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 8)))
 218  	p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 984)))
 219  	vrm := *(*uint32)(unsafe.Pointer(p1 + 80))
 220  	version = (vrm & 0x00ff0000) >> 16
 221  	release = (vrm & 0x0000ff00) >> 8
 222  	return
 223  }
 224  
 225  // returns a zos C FILE * for stdio fd 0, 1, 2
 226  func ZosStdioFilep(fd int32) uintptr {
 227  	return uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(uint64(*(*uint32)(unsafe.Pointer(uintptr(1208)))) + 80))) + uint64((fd+2)<<3))))))))
 228  }
 229  
 230  func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
 231  	stat.Dev = uint64(statLE.Dev)
 232  	stat.Ino = uint64(statLE.Ino)
 233  	stat.Nlink = uint64(statLE.Nlink)
 234  	stat.Mode = uint32(statLE.Mode)
 235  	stat.Uid = uint32(statLE.Uid)
 236  	stat.Gid = uint32(statLE.Gid)
 237  	stat.Rdev = uint64(statLE.Rdev)
 238  	stat.Size = statLE.Size
 239  	stat.Atim.Sec = int64(statLE.Atim)
 240  	stat.Atim.Nsec = 0 //zos doesn't return nanoseconds
 241  	stat.Mtim.Sec = int64(statLE.Mtim)
 242  	stat.Mtim.Nsec = 0 //zos doesn't return nanoseconds
 243  	stat.Ctim.Sec = int64(statLE.Ctim)
 244  	stat.Ctim.Nsec = 0 //zos doesn't return nanoseconds
 245  	stat.Blksize = int64(statLE.Blksize)
 246  	stat.Blocks = statLE.Blocks
 247  }
 248  
 249  func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
 250  func svcLoad(name *byte) unsafe.Pointer
 251  func svcUnload(name *byte, fnptr unsafe.Pointer) int64
 252  
 253  func (d *Dirent) NameString() string {
 254  	if d == nil {
 255  		return ""
 256  	}
 257  	s := string(d.Name[:])
 258  	idx := strings.IndexByte(s, 0)
 259  	if idx == -1 {
 260  		return s
 261  	} else {
 262  		return s[:idx]
 263  	}
 264  }
 265  
 266  func DecodeData(dest []byte, sz int, val uint64) {
 267  	for i := 0; i < sz; i++ {
 268  		dest[sz-1-i] = byte((val >> (uint64(i * 8))) & 0xff)
 269  	}
 270  }
 271  
 272  func EncodeData(data []byte) uint64 {
 273  	var value uint64
 274  	sz := len(data)
 275  	for i := 0; i < sz; i++ {
 276  		value |= uint64(data[i]) << uint64(((sz - i - 1) * 8))
 277  	}
 278  	return value
 279  }
 280  
 281  func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
 282  	if sa.Port < 0 || sa.Port > 0xFFFF {
 283  		return nil, 0, EINVAL
 284  	}
 285  	sa.raw.Len = SizeofSockaddrInet4
 286  	sa.raw.Family = AF_INET
 287  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
 288  	p[0] = byte(sa.Port >> 8)
 289  	p[1] = byte(sa.Port)
 290  	for i := 0; i < len(sa.Addr); i++ {
 291  		sa.raw.Addr[i] = sa.Addr[i]
 292  	}
 293  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
 294  }
 295  
 296  func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
 297  	if sa.Port < 0 || sa.Port > 0xFFFF {
 298  		return nil, 0, EINVAL
 299  	}
 300  	sa.raw.Len = SizeofSockaddrInet6
 301  	sa.raw.Family = AF_INET6
 302  	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
 303  	p[0] = byte(sa.Port >> 8)
 304  	p[1] = byte(sa.Port)
 305  	sa.raw.Scope_id = sa.ZoneId
 306  	for i := 0; i < len(sa.Addr); i++ {
 307  		sa.raw.Addr[i] = sa.Addr[i]
 308  	}
 309  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
 310  }
 311  
 312  func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
 313  	name := sa.Name
 314  	n := len(name)
 315  	if n >= len(sa.raw.Path) || n == 0 {
 316  		return nil, 0, EINVAL
 317  	}
 318  	sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
 319  	sa.raw.Family = AF_UNIX
 320  	for i := 0; i < n; i++ {
 321  		sa.raw.Path[i] = int8(name[i])
 322  	}
 323  	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
 324  }
 325  
 326  func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
 327  	// TODO(neeilan): Implement use of first param (fd)
 328  	switch rsa.Addr.Family {
 329  	case AF_UNIX:
 330  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
 331  		sa := new(SockaddrUnix)
 332  		// For z/OS, only replace NUL with @ when the
 333  		// length is not zero.
 334  		if pp.Len != 0 && pp.Path[0] == 0 {
 335  			// "Abstract" Unix domain socket.
 336  			// Rewrite leading NUL as @ for textual display.
 337  			// (This is the standard convention.)
 338  			// Not friendly to overwrite in place,
 339  			// but the callers below don't care.
 340  			pp.Path[0] = '@'
 341  		}
 342  
 343  		// Assume path ends at NUL.
 344  		//
 345  		// For z/OS, the length of the name is a field
 346  		// in the structure. To be on the safe side, we
 347  		// will still scan the name for a NUL but only
 348  		// to the length provided in the structure.
 349  		//
 350  		// This is not technically the Linux semantics for
 351  		// abstract Unix domain sockets--they are supposed
 352  		// to be uninterpreted fixed-size binary blobs--but
 353  		// everyone uses this convention.
 354  		n := 0
 355  		for n < int(pp.Len) && pp.Path[n] != 0 {
 356  			n++
 357  		}
 358  		sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
 359  		return sa, nil
 360  
 361  	case AF_INET:
 362  		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
 363  		sa := new(SockaddrInet4)
 364  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
 365  		sa.Port = int(p[0])<<8 + int(p[1])
 366  		for i := 0; i < len(sa.Addr); i++ {
 367  			sa.Addr[i] = pp.Addr[i]
 368  		}
 369  		return sa, nil
 370  
 371  	case AF_INET6:
 372  		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
 373  		sa := new(SockaddrInet6)
 374  		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
 375  		sa.Port = int(p[0])<<8 + int(p[1])
 376  		sa.ZoneId = pp.Scope_id
 377  		for i := 0; i < len(sa.Addr); i++ {
 378  			sa.Addr[i] = pp.Addr[i]
 379  		}
 380  		return sa, nil
 381  	}
 382  	return nil, EAFNOSUPPORT
 383  }
 384  
 385  func Accept(fd int) (nfd int, sa Sockaddr, err error) {
 386  	var rsa RawSockaddrAny
 387  	var len _Socklen = SizeofSockaddrAny
 388  	nfd, err = accept(fd, &rsa, &len)
 389  	if err != nil {
 390  		return
 391  	}
 392  	// TODO(neeilan): Remove 0 in call
 393  	sa, err = anyToSockaddr(0, &rsa)
 394  	if err != nil {
 395  		Close(nfd)
 396  		nfd = 0
 397  	}
 398  	return
 399  }
 400  
 401  func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
 402  	var rsa RawSockaddrAny
 403  	var len _Socklen = SizeofSockaddrAny
 404  	nfd, err = accept4(fd, &rsa, &len, flags)
 405  	if err != nil {
 406  		return
 407  	}
 408  	if len > SizeofSockaddrAny {
 409  		panic("RawSockaddrAny too small")
 410  	}
 411  	// TODO(neeilan): Remove 0 in call
 412  	sa, err = anyToSockaddr(0, &rsa)
 413  	if err != nil {
 414  		Close(nfd)
 415  		nfd = 0
 416  	}
 417  	return
 418  }
 419  
 420  func Ctermid() (tty string, err error) {
 421  	var termdev [1025]byte
 422  	runtime.EnterSyscall()
 423  	r0, err2, err1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___CTERMID_A<<4, uintptr(unsafe.Pointer(&termdev[0])))
 424  	runtime.ExitSyscall()
 425  	if r0 == 0 {
 426  		return "", fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
 427  	}
 428  	s := string(termdev[:])
 429  	idx := strings.Index(s, string(rune(0)))
 430  	if idx == -1 {
 431  		tty = s
 432  	} else {
 433  		tty = s[:idx]
 434  	}
 435  	return
 436  }
 437  
 438  func (iov *Iovec) SetLen(length int) {
 439  	iov.Len = uint64(length)
 440  }
 441  
 442  func (msghdr *Msghdr) SetControllen(length int) {
 443  	msghdr.Controllen = int32(length)
 444  }
 445  
 446  func (cmsg *Cmsghdr) SetLen(length int) {
 447  	cmsg.Len = int32(length)
 448  }
 449  
 450  //sys   fcntl(fd int, cmd int, arg int) (val int, err error)
 451  //sys   Flistxattr(fd int, dest []byte) (sz int, err error) = SYS___FLISTXATTR_A
 452  //sys   Fremovexattr(fd int, attr string) (err error) = SYS___FREMOVEXATTR_A
 453  //sys	read(fd int, p []byte) (n int, err error)
 454  //sys	write(fd int, p []byte) (n int, err error)
 455  
 456  //sys   Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) = SYS___FGETXATTR_A
 457  //sys   Fsetxattr(fd int, attr string, data []byte, flag int) (err error) = SYS___FSETXATTR_A
 458  
 459  //sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A
 460  //sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = SYS___ACCEPT4_A
 461  //sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A
 462  //sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A
 463  //sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
 464  //sysnb	setgroups(n int, list *_Gid_t) (err error)
 465  //sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
 466  //sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
 467  //sysnb	socket(domain int, typ int, proto int) (fd int, err error)
 468  //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
 469  //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A
 470  //sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A
 471  //sys   Removexattr(path string, attr string) (err error) = SYS___REMOVEXATTR_A
 472  //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A
 473  //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A
 474  //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A
 475  //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A
 476  //sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP
 477  //sys   munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP
 478  //sys   ioctl(fd int, req int, arg uintptr) (err error) = SYS_IOCTL
 479  //sys   ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = SYS_IOCTL
 480  //sys	shmat(id int, addr uintptr, flag int) (ret uintptr, err error) = SYS_SHMAT
 481  //sys	shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) = SYS_SHMCTL64
 482  //sys	shmdt(addr uintptr) (err error) = SYS_SHMDT
 483  //sys	shmget(key int, size int, flag int) (id int, err error) = SYS_SHMGET
 484  
 485  //sys   Access(path string, mode uint32) (err error) = SYS___ACCESS_A
 486  //sys   Chdir(path string) (err error) = SYS___CHDIR_A
 487  //sys	Chown(path string, uid int, gid int) (err error) = SYS___CHOWN_A
 488  //sys	Chmod(path string, mode uint32) (err error) = SYS___CHMOD_A
 489  //sys   Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A
 490  //sys	Dup(oldfd int) (fd int, err error)
 491  //sys	Dup2(oldfd int, newfd int) (err error)
 492  //sys	Dup3(oldfd int, newfd int, flags int) (err error) = SYS_DUP3
 493  //sys	Dirfd(dirp uintptr) (fd int, err error) = SYS_DIRFD
 494  //sys	EpollCreate(size int) (fd int, err error) = SYS_EPOLL_CREATE
 495  //sys	EpollCreate1(flags int) (fd int, err error) = SYS_EPOLL_CREATE1
 496  //sys	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) = SYS_EPOLL_CTL
 497  //sys	EpollPwait(epfd int, events []EpollEvent, msec int, sigmask *int) (n int, err error) = SYS_EPOLL_PWAIT
 498  //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_WAIT
 499  //sys	Errno2() (er2 int) = SYS___ERRNO2
 500  //sys	Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD
 501  //sys	Exit(code int)
 502  //sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error) = SYS___FACCESSAT_A
 503  
 504  func Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
 505  	return Faccessat(dirfd, path, mode, flags)
 506  }
 507  
 508  //sys	Fchdir(fd int) (err error)
 509  //sys	Fchmod(fd int, mode uint32) (err error)
 510  //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) = SYS___FCHMODAT_A
 511  //sys	Fchown(fd int, uid int, gid int) (err error)
 512  //sys	Fchownat(fd int, path string, uid int, gid int, flags int) (err error) = SYS___FCHOWNAT_A
 513  //sys	FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) = SYS_FCNTL
 514  //sys	Fdatasync(fd int) (err error) = SYS_FDATASYNC
 515  //sys	fstat(fd int, stat *Stat_LE_t) (err error)
 516  //sys	fstatat(dirfd int, path string, stat *Stat_LE_t, flags int) (err error) = SYS___FSTATAT_A
 517  
 518  func Fstat(fd int, stat *Stat_t) (err error) {
 519  	var statLE Stat_LE_t
 520  	err = fstat(fd, &statLE)
 521  	copyStat(stat, &statLE)
 522  	return
 523  }
 524  
 525  func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
 526  	var statLE Stat_LE_t
 527  	err = fstatat(dirfd, path, &statLE, flags)
 528  	copyStat(stat, &statLE)
 529  	return
 530  }
 531  
 532  func impl_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
 533  	var _p0 *byte
 534  	_p0, err = BytePtrFromString(path)
 535  	if err != nil {
 536  		return
 537  	}
 538  	var _p1 *byte
 539  	_p1, err = BytePtrFromString(attr)
 540  	if err != nil {
 541  		return
 542  	}
 543  	var _p2 unsafe.Pointer
 544  	if len(dest) > 0 {
 545  		_p2 = unsafe.Pointer(&dest[0])
 546  	} else {
 547  		_p2 = unsafe.Pointer(&_zero)
 548  	}
 549  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___GETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)))
 550  	sz = int(r0)
 551  	if int64(r0) == -1 {
 552  		err = errnoErr2(e1, e2)
 553  	}
 554  	return
 555  }
 556  
 557  //go:nosplit
 558  func get_GetxattrAddr() *(func(path string, attr string, dest []byte) (sz int, err error))
 559  
 560  var Getxattr = enter_Getxattr
 561  
 562  func enter_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
 563  	funcref := get_GetxattrAddr()
 564  	if validGetxattr() {
 565  		*funcref = impl_Getxattr
 566  	} else {
 567  		*funcref = error_Getxattr
 568  	}
 569  	return (*funcref)(path, attr, dest)
 570  }
 571  
 572  func error_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
 573  	return -1, ENOSYS
 574  }
 575  
 576  func validGetxattr() bool {
 577  	if funcptrtest(GetZosLibVec()+SYS___GETXATTR_A<<4, "") == 0 {
 578  		if name, err := getLeFuncName(GetZosLibVec() + SYS___GETXATTR_A<<4); err == nil {
 579  			return name == "__getxattr_a"
 580  		}
 581  	}
 582  	return false
 583  }
 584  
 585  //sys   Lgetxattr(link string, attr string, dest []byte) (sz int, err error) = SYS___LGETXATTR_A
 586  //sys   Lsetxattr(path string, attr string, data []byte, flags int) (err error) = SYS___LSETXATTR_A
 587  
 588  func impl_Setxattr(path string, attr string, data []byte, flags int) (err error) {
 589  	var _p0 *byte
 590  	_p0, err = BytePtrFromString(path)
 591  	if err != nil {
 592  		return
 593  	}
 594  	var _p1 *byte
 595  	_p1, err = BytePtrFromString(attr)
 596  	if err != nil {
 597  		return
 598  	}
 599  	var _p2 unsafe.Pointer
 600  	if len(data) > 0 {
 601  		_p2 = unsafe.Pointer(&data[0])
 602  	} else {
 603  		_p2 = unsafe.Pointer(&_zero)
 604  	}
 605  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags))
 606  	if int64(r0) == -1 {
 607  		err = errnoErr2(e1, e2)
 608  	}
 609  	return
 610  }
 611  
 612  //go:nosplit
 613  func get_SetxattrAddr() *(func(path string, attr string, data []byte, flags int) (err error))
 614  
 615  var Setxattr = enter_Setxattr
 616  
 617  func enter_Setxattr(path string, attr string, data []byte, flags int) (err error) {
 618  	funcref := get_SetxattrAddr()
 619  	if validSetxattr() {
 620  		*funcref = impl_Setxattr
 621  	} else {
 622  		*funcref = error_Setxattr
 623  	}
 624  	return (*funcref)(path, attr, data, flags)
 625  }
 626  
 627  func error_Setxattr(path string, attr string, data []byte, flags int) (err error) {
 628  	return ENOSYS
 629  }
 630  
 631  func validSetxattr() bool {
 632  	if funcptrtest(GetZosLibVec()+SYS___SETXATTR_A<<4, "") == 0 {
 633  		if name, err := getLeFuncName(GetZosLibVec() + SYS___SETXATTR_A<<4); err == nil {
 634  			return name == "__setxattr_a"
 635  		}
 636  	}
 637  	return false
 638  }
 639  
 640  //sys	Fstatfs(fd int, buf *Statfs_t) (err error) = SYS_FSTATFS
 641  //sys	Fstatvfs(fd int, stat *Statvfs_t) (err error) = SYS_FSTATVFS
 642  //sys	Fsync(fd int) (err error)
 643  //sys	Futimes(fd int, tv []Timeval) (err error) = SYS_FUTIMES
 644  //sys	Futimesat(dirfd int, path string, tv []Timeval) (err error) = SYS___FUTIMESAT_A
 645  //sys	Ftruncate(fd int, length int64) (err error)
 646  //sys	Getrandom(buf []byte, flags int) (n int, err error) = SYS_GETRANDOM
 647  //sys	InotifyInit() (fd int, err error) = SYS_INOTIFY_INIT
 648  //sys	InotifyInit1(flags int) (fd int, err error) = SYS_INOTIFY_INIT1
 649  //sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) = SYS___INOTIFY_ADD_WATCH_A
 650  //sys	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) = SYS_INOTIFY_RM_WATCH
 651  //sys   Listxattr(path string, dest []byte) (sz int, err error) = SYS___LISTXATTR_A
 652  //sys   Llistxattr(path string, dest []byte) (sz int, err error) = SYS___LLISTXATTR_A
 653  //sys   Lremovexattr(path string, attr string) (err error) = SYS___LREMOVEXATTR_A
 654  //sys	Lutimes(path string, tv []Timeval) (err error) = SYS___LUTIMES_A
 655  //sys   Mprotect(b []byte, prot int) (err error) = SYS_MPROTECT
 656  //sys   Msync(b []byte, flags int) (err error) = SYS_MSYNC
 657  //sys   Console2(cmsg *ConsMsg2, modstr *byte, concmd *uint32) (err error) = SYS___CONSOLE2
 658  
 659  // Pipe2 begin
 660  
 661  //go:nosplit
 662  func getPipe2Addr() *(func([]int, int) error)
 663  
 664  var Pipe2 = pipe2Enter
 665  
 666  func pipe2Enter(p []int, flags int) (err error) {
 667  	if funcptrtest(GetZosLibVec()+SYS_PIPE2<<4, "") == 0 {
 668  		*getPipe2Addr() = pipe2Impl
 669  	} else {
 670  		*getPipe2Addr() = pipe2Error
 671  	}
 672  	return (*getPipe2Addr())(p, flags)
 673  }
 674  
 675  func pipe2Impl(p []int, flags int) (err error) {
 676  	var pp [2]_C_int
 677  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PIPE2<<4, uintptr(unsafe.Pointer(&pp[0])), uintptr(flags))
 678  	if int64(r0) == -1 {
 679  		err = errnoErr2(e1, e2)
 680  	} else {
 681  		p[0] = int(pp[0])
 682  		p[1] = int(pp[1])
 683  	}
 684  	return
 685  }
 686  func pipe2Error(p []int, flags int) (err error) {
 687  	return fmt.Errorf("Pipe2 is not available on this system")
 688  }
 689  
 690  // Pipe2 end
 691  
 692  //sys   Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL
 693  
 694  func Readdir(dir uintptr) (dirent *Dirent, err error) {
 695  	runtime.EnterSyscall()
 696  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READDIR_A<<4, uintptr(dir))
 697  	runtime.ExitSyscall()
 698  	dirent = (*Dirent)(unsafe.Pointer(r0))
 699  	if int64(r0) == -1 {
 700  		err = errnoErr2(e1, e2)
 701  	}
 702  	return
 703  }
 704  
 705  //sys	Readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) = SYS___READDIR_R_A
 706  //sys	Statfs(path string, buf *Statfs_t) (err error) = SYS___STATFS_A
 707  //sys	Syncfs(fd int) (err error) = SYS_SYNCFS
 708  //sys   Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES
 709  //sys   W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT
 710  //sys   W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A
 711  
 712  //sys   mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
 713  //sys   unmount_LE(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
 714  //sys   Chroot(path string) (err error) = SYS___CHROOT_A
 715  //sys   Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT
 716  //sysnb Uname(buf *Utsname) (err error) = SYS_____OSNAME_A
 717  //sys   Unshare(flags int) (err error) = SYS_UNSHARE
 718  
 719  func Ptsname(fd int) (name string, err error) {
 720  	runtime.EnterSyscall()
 721  	r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___PTSNAME_A<<4, uintptr(fd))
 722  	runtime.ExitSyscall()
 723  	if r0 == 0 {
 724  		err = errnoErr2(e1, e2)
 725  	} else {
 726  		name = u2s(unsafe.Pointer(r0))
 727  	}
 728  	return
 729  }
 730  
 731  func u2s(cstr unsafe.Pointer) string {
 732  	str := (*[1024]uint8)(cstr)
 733  	i := 0
 734  	for str[i] != 0 {
 735  		i++
 736  	}
 737  	return string(str[:i])
 738  }
 739  
 740  func Close(fd int) (err error) {
 741  	runtime.EnterSyscall()
 742  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))
 743  	runtime.ExitSyscall()
 744  	for i := 0; e1 == EAGAIN && i < 10; i++ {
 745  		runtime.EnterSyscall()
 746  		CallLeFuncWithErr(GetZosLibVec()+SYS_USLEEP<<4, uintptr(10))
 747  		runtime.ExitSyscall()
 748  		runtime.EnterSyscall()
 749  		r0, e2, e1 = CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))
 750  		runtime.ExitSyscall()
 751  	}
 752  	if r0 != 0 {
 753  		err = errnoErr2(e1, e2)
 754  	}
 755  	return
 756  }
 757  
 758  // Dummy function: there are no semantics for Madvise on z/OS
 759  func Madvise(b []byte, advice int) (err error) {
 760  	return
 761  }
 762  
 763  func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
 764  	return mapper.Mmap(fd, offset, length, prot, flags)
 765  }
 766  
 767  func Munmap(b []byte) (err error) {
 768  	return mapper.Munmap(b)
 769  }
 770  
 771  func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
 772  	xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
 773  	return unsafe.Pointer(xaddr), err
 774  }
 775  
 776  func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
 777  	return mapper.munmap(uintptr(addr), length)
 778  }
 779  
 780  //sys   Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
 781  //sysnb	Getgid() (gid int)
 782  //sysnb	Getpid() (pid int)
 783  //sysnb	Getpgid(pid int) (pgid int, err error) = SYS_GETPGID
 784  
 785  func Getpgrp() (pid int) {
 786  	pid, _ = Getpgid(0)
 787  	return
 788  }
 789  
 790  //sysnb	Getppid() (pid int)
 791  //sys	Getpriority(which int, who int) (prio int, err error)
 792  //sysnb	Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT
 793  
 794  //sysnb getrusage(who int, rusage *rusage_zos) (err error) = SYS_GETRUSAGE
 795  
 796  func Getrusage(who int, rusage *Rusage) (err error) {
 797  	var ruz rusage_zos
 798  	err = getrusage(who, &ruz)
 799  	//Only the first two fields of Rusage are set
 800  	rusage.Utime.Sec = ruz.Utime.Sec
 801  	rusage.Utime.Usec = int64(ruz.Utime.Usec)
 802  	rusage.Stime.Sec = ruz.Stime.Sec
 803  	rusage.Stime.Usec = int64(ruz.Stime.Usec)
 804  	return
 805  }
 806  
 807  //sys	Getegid() (egid int) = SYS_GETEGID
 808  //sys	Geteuid() (euid int) = SYS_GETEUID
 809  //sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID
 810  //sysnb	Getuid() (uid int)
 811  //sysnb	Kill(pid int, sig Signal) (err error)
 812  //sys	Lchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A
 813  //sys	Link(path string, link string) (err error) = SYS___LINK_A
 814  //sys	Linkat(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error) = SYS___LINKAT_A
 815  //sys	Listen(s int, n int) (err error)
 816  //sys	lstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A
 817  
 818  func Lstat(path string, stat *Stat_t) (err error) {
 819  	var statLE Stat_LE_t
 820  	err = lstat(path, &statLE)
 821  	copyStat(stat, &statLE)
 822  	return
 823  }
 824  
 825  // for checking symlinks begins with $VERSION/ $SYSNAME/ $SYSSYMR/ $SYSSYMA/
 826  func isSpecialPath(path []byte) (v bool) {
 827  	var special = [4][8]byte{
 828  		{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},
 829  		{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},
 830  		{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},
 831  		{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}
 832  
 833  	var i, j int
 834  	for i = 0; i < len(special); i++ {
 835  		for j = 0; j < len(special[i]); j++ {
 836  			if path[j] != special[i][j] {
 837  				break
 838  			}
 839  		}
 840  		if j == len(special[i]) {
 841  			return true
 842  		}
 843  	}
 844  	return false
 845  }
 846  
 847  func realpath(srcpath string, abspath []byte) (pathlen int, errno int) {
 848  	var source [1024]byte
 849  	copy(source[:], srcpath)
 850  	source[len(srcpath)] = 0
 851  	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___REALPATH_A<<4, //__realpath_a()
 852  		[]uintptr{uintptr(unsafe.Pointer(&source[0])),
 853  			uintptr(unsafe.Pointer(&abspath[0]))})
 854  	if ret != 0 {
 855  		index := bytes.IndexByte(abspath[:], byte(0))
 856  		if index != -1 {
 857  			return index, 0
 858  		}
 859  	} else {
 860  		errptr := (*int)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{}))) //__errno()
 861  		return 0, *errptr
 862  	}
 863  	return 0, 245 // EBADDATA   245
 864  }
 865  
 866  func Readlink(path string, buf []byte) (n int, err error) {
 867  	var _p0 *byte
 868  	_p0, err = BytePtrFromString(path)
 869  	if err != nil {
 870  		return
 871  	}
 872  	var _p1 unsafe.Pointer
 873  	if len(buf) > 0 {
 874  		_p1 = unsafe.Pointer(&buf[0])
 875  	} else {
 876  		_p1 = unsafe.Pointer(&_zero)
 877  	}
 878  	n = int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___READLINK_A<<4,
 879  		[]uintptr{uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))}))
 880  	runtime.KeepAlive(unsafe.Pointer(_p0))
 881  	if n == -1 {
 882  		value := *(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))
 883  		err = errnoErr(Errno(value))
 884  	} else {
 885  		if buf[0] == '$' {
 886  			if isSpecialPath(buf[1:9]) {
 887  				cnt, err1 := realpath(path, buf)
 888  				if err1 == 0 {
 889  					n = cnt
 890  				}
 891  			}
 892  		}
 893  	}
 894  	return
 895  }
 896  
 897  func impl_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
 898  	var _p0 *byte
 899  	_p0, err = BytePtrFromString(path)
 900  	if err != nil {
 901  		return
 902  	}
 903  	var _p1 unsafe.Pointer
 904  	if len(buf) > 0 {
 905  		_p1 = unsafe.Pointer(&buf[0])
 906  	} else {
 907  		_p1 = unsafe.Pointer(&_zero)
 908  	}
 909  	runtime.EnterSyscall()
 910  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READLINKAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 911  	runtime.ExitSyscall()
 912  	n = int(r0)
 913  	if int64(r0) == -1 {
 914  		err = errnoErr2(e1, e2)
 915  		return n, err
 916  	} else {
 917  		if buf[0] == '$' {
 918  			if isSpecialPath(buf[1:9]) {
 919  				cnt, err1 := realpath(path, buf)
 920  				if err1 == 0 {
 921  					n = cnt
 922  				}
 923  			}
 924  		}
 925  	}
 926  	return
 927  }
 928  
 929  //go:nosplit
 930  func get_ReadlinkatAddr() *(func(dirfd int, path string, buf []byte) (n int, err error))
 931  
 932  var Readlinkat = enter_Readlinkat
 933  
 934  func enter_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
 935  	funcref := get_ReadlinkatAddr()
 936  	if funcptrtest(GetZosLibVec()+SYS___READLINKAT_A<<4, "") == 0 {
 937  		*funcref = impl_Readlinkat
 938  	} else {
 939  		*funcref = error_Readlinkat
 940  	}
 941  	return (*funcref)(dirfd, path, buf)
 942  }
 943  
 944  func error_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
 945  	n = -1
 946  	err = ENOSYS
 947  	return
 948  }
 949  
 950  //sys	Mkdir(path string, mode uint32) (err error) = SYS___MKDIR_A
 951  //sys	Mkdirat(dirfd int, path string, mode uint32) (err error) = SYS___MKDIRAT_A
 952  //sys   Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A
 953  //sys	Mknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A
 954  //sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error) = SYS___MKNODAT_A
 955  //sys	PivotRoot(newroot string, oldroot string) (err error) = SYS___PIVOT_ROOT_A
 956  //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
 957  //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
 958  //sys	Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) = SYS___PRCTL_A
 959  //sysnb	Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT
 960  //sys	Rename(from string, to string) (err error) = SYS___RENAME_A
 961  //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) = SYS___RENAMEAT_A
 962  //sys	Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) = SYS___RENAMEAT2_A
 963  //sys	Rmdir(path string) (err error) = SYS___RMDIR_A
 964  //sys   Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
 965  //sys	Setegid(egid int) (err error) = SYS_SETEGID
 966  //sys	Seteuid(euid int) (err error) = SYS_SETEUID
 967  //sys	Sethostname(p []byte) (err error) = SYS___SETHOSTNAME_A
 968  //sys   Setns(fd int, nstype int) (err error) = SYS_SETNS
 969  //sys	Setpriority(which int, who int, prio int) (err error)
 970  //sysnb	Setpgid(pid int, pgid int) (err error) = SYS_SETPGID
 971  //sysnb	Setrlimit(resource int, lim *Rlimit) (err error)
 972  //sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID
 973  //sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID
 974  //sysnb	Setsid() (pid int, err error) = SYS_SETSID
 975  //sys	Setuid(uid int) (err error) = SYS_SETUID
 976  //sys	Setgid(uid int) (err error) = SYS_SETGID
 977  //sys	Shutdown(fd int, how int) (err error)
 978  //sys	stat(path string, statLE *Stat_LE_t) (err error) = SYS___STAT_A
 979  
 980  func Stat(path string, sta *Stat_t) (err error) {
 981  	var statLE Stat_LE_t
 982  	err = stat(path, &statLE)
 983  	copyStat(sta, &statLE)
 984  	return
 985  }
 986  
 987  //sys	Symlink(path string, link string) (err error) = SYS___SYMLINK_A
 988  //sys	Symlinkat(oldPath string, dirfd int, newPath string) (err error) = SYS___SYMLINKAT_A
 989  //sys	Sync() = SYS_SYNC
 990  //sys	Truncate(path string, length int64) (err error) = SYS___TRUNCATE_A
 991  //sys	Tcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR
 992  //sys	Tcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR
 993  //sys	Umask(mask int) (oldmask int)
 994  //sys	Unlink(path string) (err error) = SYS___UNLINK_A
 995  //sys	Unlinkat(dirfd int, path string, flags int) (err error) = SYS___UNLINKAT_A
 996  //sys	Utime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A
 997  
 998  //sys	open(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A
 999  
1000  func Open(path string, mode int, perm uint32) (fd int, err error) {
1001  	if mode&O_ACCMODE == 0 {
1002  		mode |= O_RDONLY
1003  	}
1004  	return open(path, mode, perm)
1005  }
1006  
1007  //sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) = SYS___OPENAT_A
1008  
1009  func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
1010  	if flags&O_ACCMODE == 0 {
1011  		flags |= O_RDONLY
1012  	}
1013  	return openat(dirfd, path, flags, mode)
1014  }
1015  
1016  //sys	openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) = SYS___OPENAT2_A
1017  
1018  func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
1019  	if how.Flags&O_ACCMODE == 0 {
1020  		how.Flags |= O_RDONLY
1021  	}
1022  	return openat2(dirfd, path, how, SizeofOpenHow)
1023  }
1024  
1025  func ZosFdToPath(dirfd int) (path string, err error) {
1026  	var buffer [1024]byte
1027  	runtime.EnterSyscall()
1028  	ret, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_W_IOCTL<<4, uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0])))
1029  	runtime.ExitSyscall()
1030  	if ret == 0 {
1031  		zb := bytes.IndexByte(buffer[:], 0)
1032  		if zb == -1 {
1033  			zb = len(buffer)
1034  		}
1035  		CallLeFuncWithErr(GetZosLibVec()+SYS___E2A_L<<4, uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb))
1036  		return string(buffer[:zb]), nil
1037  	}
1038  	return "", errnoErr2(e1, e2)
1039  }
1040  
1041  //sys	remove(path string) (err error)
1042  
1043  func Remove(path string) error {
1044  	return remove(path)
1045  }
1046  
1047  const ImplementsGetwd = true
1048  
1049  func Getcwd(buf []byte) (n int, err error) {
1050  	var p unsafe.Pointer
1051  	if len(buf) > 0 {
1052  		p = unsafe.Pointer(&buf[0])
1053  	} else {
1054  		p = unsafe.Pointer(&_zero)
1055  	}
1056  	runtime.EnterSyscall()
1057  	r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___GETCWD_A<<4, uintptr(p), uintptr(len(buf)))
1058  	runtime.ExitSyscall()
1059  	n = clen(buf) + 1
1060  	if r0 == 0 {
1061  		err = errnoErr2(e1, e2)
1062  	}
1063  	return
1064  }
1065  
1066  func Getwd() (wd string, err error) {
1067  	var buf [PathMax]byte
1068  	n, err := Getcwd(buf[0:])
1069  	if err != nil {
1070  		return "", err
1071  	}
1072  	// Getcwd returns the number of bytes written to buf, including the NUL.
1073  	if n < 1 || n > len(buf) || buf[n-1] != 0 {
1074  		return "", EINVAL
1075  	}
1076  	return string(buf[0 : n-1]), nil
1077  }
1078  
1079  func Getgroups() (gids []int, err error) {
1080  	n, err := getgroups(0, nil)
1081  	if err != nil {
1082  		return nil, err
1083  	}
1084  	if n == 0 {
1085  		return nil, nil
1086  	}
1087  
1088  	// Sanity check group count.  Max is 1<<16 on Linux.
1089  	if n < 0 || n > 1<<20 {
1090  		return nil, EINVAL
1091  	}
1092  
1093  	a := make([]_Gid_t, n)
1094  	n, err = getgroups(n, &a[0])
1095  	if err != nil {
1096  		return nil, err
1097  	}
1098  	gids = make([]int, n)
1099  	for i, v := range a[0:n] {
1100  		gids[i] = int(v)
1101  	}
1102  	return
1103  }
1104  
1105  func Setgroups(gids []int) (err error) {
1106  	if len(gids) == 0 {
1107  		return setgroups(0, nil)
1108  	}
1109  
1110  	a := make([]_Gid_t, len(gids))
1111  	for i, v := range gids {
1112  		a[i] = _Gid_t(v)
1113  	}
1114  	return setgroups(len(a), &a[0])
1115  }
1116  
1117  func gettid() uint64
1118  
1119  func Gettid() (tid int) {
1120  	return int(gettid())
1121  }
1122  
1123  type WaitStatus uint32
1124  
1125  // Wait status is 7 bits at bottom, either 0 (exited),
1126  // 0x7F (stopped), or a signal number that caused an exit.
1127  // The 0x80 bit is whether there was a core dump.
1128  // An extra number (exit code, signal causing a stop)
1129  // is in the high bits.  At least that's the idea.
1130  // There are various irregularities.  For example, the
1131  // "continued" status is 0xFFFF, distinguishing itself
1132  // from stopped via the core dump bit.
1133  
1134  const (
1135  	mask    = 0x7F
1136  	core    = 0x80
1137  	exited  = 0x00
1138  	stopped = 0x7F
1139  	shift   = 8
1140  )
1141  
1142  func (w WaitStatus) Exited() bool { return w&mask == exited }
1143  
1144  func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
1145  
1146  func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
1147  
1148  func (w WaitStatus) Continued() bool { return w == 0xFFFF }
1149  
1150  func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
1151  
1152  func (w WaitStatus) ExitStatus() int {
1153  	if !w.Exited() {
1154  		return -1
1155  	}
1156  	return int(w>>shift) & 0xFF
1157  }
1158  
1159  func (w WaitStatus) Signal() Signal {
1160  	if !w.Signaled() {
1161  		return -1
1162  	}
1163  	return Signal(w & mask)
1164  }
1165  
1166  func (w WaitStatus) StopSignal() Signal {
1167  	if !w.Stopped() {
1168  		return -1
1169  	}
1170  	return Signal(w>>shift) & 0xFF
1171  }
1172  
1173  func (w WaitStatus) TrapCause() int { return -1 }
1174  
1175  //sys	waitid(idType int, id int, info *Siginfo, options int) (err error)
1176  
1177  func Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) {
1178  	return waitid(idType, id, info, options)
1179  }
1180  
1181  //sys	waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)
1182  
1183  func impl_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1184  	runtime.EnterSyscall()
1185  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAIT4<<4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)))
1186  	runtime.ExitSyscall()
1187  	wpid = int(r0)
1188  	if int64(r0) == -1 {
1189  		err = errnoErr2(e1, e2)
1190  	}
1191  	return
1192  }
1193  
1194  //go:nosplit
1195  func get_Wait4Addr() *(func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error))
1196  
1197  var Wait4 = enter_Wait4
1198  
1199  func enter_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1200  	funcref := get_Wait4Addr()
1201  	if funcptrtest(GetZosLibVec()+SYS_WAIT4<<4, "") == 0 {
1202  		*funcref = impl_Wait4
1203  	} else {
1204  		*funcref = legacyWait4
1205  	}
1206  	return (*funcref)(pid, wstatus, options, rusage)
1207  }
1208  
1209  func legacyWait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1210  	// TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.
1211  	// At the moment rusage will not be touched.
1212  	var status _C_int
1213  	wpid, err = waitpid(pid, &status, options)
1214  	if wstatus != nil {
1215  		*wstatus = WaitStatus(status)
1216  	}
1217  	return
1218  }
1219  
1220  //sysnb	gettimeofday(tv *timeval_zos) (err error)
1221  
1222  func Gettimeofday(tv *Timeval) (err error) {
1223  	var tvz timeval_zos
1224  	err = gettimeofday(&tvz)
1225  	tv.Sec = tvz.Sec
1226  	tv.Usec = int64(tvz.Usec)
1227  	return
1228  }
1229  
1230  func Time(t *Time_t) (tt Time_t, err error) {
1231  	var tv Timeval
1232  	err = Gettimeofday(&tv)
1233  	if err != nil {
1234  		return 0, err
1235  	}
1236  	if t != nil {
1237  		*t = Time_t(tv.Sec)
1238  	}
1239  	return Time_t(tv.Sec), nil
1240  }
1241  
1242  func setTimespec(sec, nsec int64) Timespec {
1243  	return Timespec{Sec: sec, Nsec: nsec}
1244  }
1245  
1246  func setTimeval(sec, usec int64) Timeval { //fix
1247  	return Timeval{Sec: sec, Usec: usec}
1248  }
1249  
1250  //sysnb pipe(p *[2]_C_int) (err error)
1251  
1252  func Pipe(p []int) (err error) {
1253  	if len(p) != 2 {
1254  		return EINVAL
1255  	}
1256  	var pp [2]_C_int
1257  	err = pipe(&pp)
1258  	p[0] = int(pp[0])
1259  	p[1] = int(pp[1])
1260  	return
1261  }
1262  
1263  //sys	utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
1264  
1265  func Utimes(path string, tv []Timeval) (err error) {
1266  	if tv == nil {
1267  		return utimes(path, nil)
1268  	}
1269  	if len(tv) != 2 {
1270  		return EINVAL
1271  	}
1272  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
1273  }
1274  
1275  //sys	utimensat(dirfd int, path string, ts *[2]Timespec, flags int) (err error) = SYS___UTIMENSAT_A
1276  
1277  func validUtimensat() bool {
1278  	if funcptrtest(GetZosLibVec()+SYS___UTIMENSAT_A<<4, "") == 0 {
1279  		if name, err := getLeFuncName(GetZosLibVec() + SYS___UTIMENSAT_A<<4); err == nil {
1280  			return name == "__utimensat_a"
1281  		}
1282  	}
1283  	return false
1284  }
1285  
1286  // Begin UtimesNano
1287  
1288  //go:nosplit
1289  func get_UtimesNanoAddr() *(func(path string, ts []Timespec) (err error))
1290  
1291  var UtimesNano = enter_UtimesNano
1292  
1293  func enter_UtimesNano(path string, ts []Timespec) (err error) {
1294  	funcref := get_UtimesNanoAddr()
1295  	if validUtimensat() {
1296  		*funcref = utimesNanoImpl
1297  	} else {
1298  		*funcref = legacyUtimesNano
1299  	}
1300  	return (*funcref)(path, ts)
1301  }
1302  
1303  func utimesNanoImpl(path string, ts []Timespec) (err error) {
1304  	if ts == nil {
1305  		return utimensat(AT_FDCWD, path, nil, 0)
1306  	}
1307  	if len(ts) != 2 {
1308  		return EINVAL
1309  	}
1310  	return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
1311  }
1312  
1313  func legacyUtimesNano(path string, ts []Timespec) (err error) {
1314  	if len(ts) != 2 {
1315  		return EINVAL
1316  	}
1317  	// Not as efficient as it could be because Timespec and
1318  	// Timeval have different types in the different OSes
1319  	tv := [2]Timeval{
1320  		NsecToTimeval(TimespecToNsec(ts[0])),
1321  		NsecToTimeval(TimespecToNsec(ts[1])),
1322  	}
1323  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
1324  }
1325  
1326  // End UtimesNano
1327  
1328  // Begin UtimesNanoAt
1329  
1330  //go:nosplit
1331  func get_UtimesNanoAtAddr() *(func(dirfd int, path string, ts []Timespec, flags int) (err error))
1332  
1333  var UtimesNanoAt = enter_UtimesNanoAt
1334  
1335  func enter_UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
1336  	funcref := get_UtimesNanoAtAddr()
1337  	if validUtimensat() {
1338  		*funcref = utimesNanoAtImpl
1339  	} else {
1340  		*funcref = legacyUtimesNanoAt
1341  	}
1342  	return (*funcref)(dirfd, path, ts, flags)
1343  }
1344  
1345  func utimesNanoAtImpl(dirfd int, path string, ts []Timespec, flags int) (err error) {
1346  	if ts == nil {
1347  		return utimensat(dirfd, path, nil, flags)
1348  	}
1349  	if len(ts) != 2 {
1350  		return EINVAL
1351  	}
1352  	return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
1353  }
1354  
1355  func legacyUtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
1356  	if path[0] != '/' {
1357  		dirPath, err := ZosFdToPath(dirfd)
1358  		if err != nil {
1359  			return err
1360  		}
1361  		path = dirPath + "/" + path
1362  	}
1363  	if flags == AT_SYMLINK_NOFOLLOW {
1364  		if len(ts) != 2 {
1365  			return EINVAL
1366  		}
1367  
1368  		if ts[0].Nsec >= 5e8 {
1369  			ts[0].Sec++
1370  		}
1371  		ts[0].Nsec = 0
1372  		if ts[1].Nsec >= 5e8 {
1373  			ts[1].Sec++
1374  		}
1375  		ts[1].Nsec = 0
1376  
1377  		// Not as efficient as it could be because Timespec and
1378  		// Timeval have different types in the different OSes
1379  		tv := []Timeval{
1380  			NsecToTimeval(TimespecToNsec(ts[0])),
1381  			NsecToTimeval(TimespecToNsec(ts[1])),
1382  		}
1383  		return Lutimes(path, tv)
1384  	}
1385  	return UtimesNano(path, ts)
1386  }
1387  
1388  // End UtimesNanoAt
1389  
1390  func Getsockname(fd int) (sa Sockaddr, err error) {
1391  	var rsa RawSockaddrAny
1392  	var len _Socklen = SizeofSockaddrAny
1393  	if err = getsockname(fd, &rsa, &len); err != nil {
1394  		return
1395  	}
1396  	// TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )
1397  	return anyToSockaddr(0, &rsa)
1398  }
1399  
1400  const (
1401  	// identifier constants
1402  	nwmHeaderIdentifier    = 0xd5e6d4c8
1403  	nwmFilterIdentifier    = 0xd5e6d4c6
1404  	nwmTCPConnIdentifier   = 0xd5e6d4c3
1405  	nwmRecHeaderIdentifier = 0xd5e6d4d9
1406  	nwmIPStatsIdentifier   = 0xd5e6d4c9d7e2e340
1407  	nwmIPGStatsIdentifier  = 0xd5e6d4c9d7c7e2e3
1408  	nwmTCPStatsIdentifier  = 0xd5e6d4e3c3d7e2e3
1409  	nwmUDPStatsIdentifier  = 0xd5e6d4e4c4d7e2e3
1410  	nwmICMPGStatsEntry     = 0xd5e6d4c9c3d4d7c7
1411  	nwmICMPTStatsEntry     = 0xd5e6d4c9c3d4d7e3
1412  
1413  	// nwmHeader constants
1414  	nwmVersion1   = 1
1415  	nwmVersion2   = 2
1416  	nwmCurrentVer = 2
1417  
1418  	nwmTCPConnType     = 1
1419  	nwmGlobalStatsType = 14
1420  
1421  	// nwmFilter constants
1422  	nwmFilterLclAddrMask = 0x20000000 // Local address
1423  	nwmFilterSrcAddrMask = 0x20000000 // Source address
1424  	nwmFilterLclPortMask = 0x10000000 // Local port
1425  	nwmFilterSrcPortMask = 0x10000000 // Source port
1426  
1427  	// nwmConnEntry constants
1428  	nwmTCPStateClosed   = 1
1429  	nwmTCPStateListen   = 2
1430  	nwmTCPStateSynSent  = 3
1431  	nwmTCPStateSynRcvd  = 4
1432  	nwmTCPStateEstab    = 5
1433  	nwmTCPStateFinWait1 = 6
1434  	nwmTCPStateFinWait2 = 7
1435  	nwmTCPStateClosWait = 8
1436  	nwmTCPStateLastAck  = 9
1437  	nwmTCPStateClosing  = 10
1438  	nwmTCPStateTimeWait = 11
1439  	nwmTCPStateDeletTCB = 12
1440  
1441  	// Existing constants on linux
1442  	BPF_TCP_CLOSE        = 1
1443  	BPF_TCP_LISTEN       = 2
1444  	BPF_TCP_SYN_SENT     = 3
1445  	BPF_TCP_SYN_RECV     = 4
1446  	BPF_TCP_ESTABLISHED  = 5
1447  	BPF_TCP_FIN_WAIT1    = 6
1448  	BPF_TCP_FIN_WAIT2    = 7
1449  	BPF_TCP_CLOSE_WAIT   = 8
1450  	BPF_TCP_LAST_ACK     = 9
1451  	BPF_TCP_CLOSING      = 10
1452  	BPF_TCP_TIME_WAIT    = 11
1453  	BPF_TCP_NEW_SYN_RECV = -1
1454  	BPF_TCP_MAX_STATES   = -2
1455  )
1456  
1457  type nwmTriplet struct {
1458  	offset uint32
1459  	length uint32
1460  	number uint32
1461  }
1462  
1463  type nwmQuadruplet struct {
1464  	offset uint32
1465  	length uint32
1466  	number uint32
1467  	match  uint32
1468  }
1469  
1470  type nwmHeader struct {
1471  	ident       uint32
1472  	length      uint32
1473  	version     uint16
1474  	nwmType     uint16
1475  	bytesNeeded uint32
1476  	options     uint32
1477  	_           [16]byte
1478  	inputDesc   nwmTriplet
1479  	outputDesc  nwmQuadruplet
1480  }
1481  
1482  type nwmFilter struct {
1483  	ident         uint32
1484  	flags         uint32
1485  	resourceName  [8]byte
1486  	resourceId    uint32
1487  	listenerId    uint32
1488  	local         [28]byte // union of sockaddr4 and sockaddr6
1489  	remote        [28]byte // union of sockaddr4 and sockaddr6
1490  	_             uint16
1491  	_             uint16
1492  	asid          uint16
1493  	_             [2]byte
1494  	tnLuName      [8]byte
1495  	tnMonGrp      uint32
1496  	tnAppl        [8]byte
1497  	applData      [40]byte
1498  	nInterface    [16]byte
1499  	dVipa         [16]byte
1500  	dVipaPfx      uint16
1501  	dVipaPort     uint16
1502  	dVipaFamily   byte
1503  	_             [3]byte
1504  	destXCF       [16]byte
1505  	destXCFPfx    uint16
1506  	destXCFFamily byte
1507  	_             [1]byte
1508  	targIP        [16]byte
1509  	targIPPfx     uint16
1510  	targIPFamily  byte
1511  	_             [1]byte
1512  	_             [20]byte
1513  }
1514  
1515  type nwmRecHeader struct {
1516  	ident  uint32
1517  	length uint32
1518  	number byte
1519  	_      [3]byte
1520  }
1521  
1522  type nwmTCPStatsEntry struct {
1523  	ident             uint64
1524  	currEstab         uint32
1525  	activeOpened      uint32
1526  	passiveOpened     uint32
1527  	connClosed        uint32
1528  	estabResets       uint32
1529  	attemptFails      uint32
1530  	passiveDrops      uint32
1531  	timeWaitReused    uint32
1532  	inSegs            uint64
1533  	predictAck        uint32
1534  	predictData       uint32
1535  	inDupAck          uint32
1536  	inBadSum          uint32
1537  	inBadLen          uint32
1538  	inShort           uint32
1539  	inDiscOldTime     uint32
1540  	inAllBeforeWin    uint32
1541  	inSomeBeforeWin   uint32
1542  	inAllAfterWin     uint32
1543  	inSomeAfterWin    uint32
1544  	inOutOfOrder      uint32
1545  	inAfterClose      uint32
1546  	inWinProbes       uint32
1547  	inWinUpdates      uint32
1548  	outWinUpdates     uint32
1549  	outSegs           uint64
1550  	outDelayAcks      uint32
1551  	outRsts           uint32
1552  	retransSegs       uint32
1553  	retransTimeouts   uint32
1554  	retransDrops      uint32
1555  	pmtuRetrans       uint32
1556  	pmtuErrors        uint32
1557  	outWinProbes      uint32
1558  	probeDrops        uint32
1559  	keepAliveProbes   uint32
1560  	keepAliveDrops    uint32
1561  	finwait2Drops     uint32
1562  	acceptCount       uint64
1563  	inBulkQSegs       uint64
1564  	inDiscards        uint64
1565  	connFloods        uint32
1566  	connStalls        uint32
1567  	cfgEphemDef       uint16
1568  	ephemInUse        uint16
1569  	ephemHiWater      uint16
1570  	flags             byte
1571  	_                 [1]byte
1572  	ephemExhaust      uint32
1573  	smcRCurrEstabLnks uint32
1574  	smcRLnkActTimeOut uint32
1575  	smcRActLnkOpened  uint32
1576  	smcRPasLnkOpened  uint32
1577  	smcRLnksClosed    uint32
1578  	smcRCurrEstab     uint32
1579  	smcRActiveOpened  uint32
1580  	smcRPassiveOpened uint32
1581  	smcRConnClosed    uint32
1582  	smcRInSegs        uint64
1583  	smcROutSegs       uint64
1584  	smcRInRsts        uint32
1585  	smcROutRsts       uint32
1586  	smcDCurrEstabLnks uint32
1587  	smcDActLnkOpened  uint32
1588  	smcDPasLnkOpened  uint32
1589  	smcDLnksClosed    uint32
1590  	smcDCurrEstab     uint32
1591  	smcDActiveOpened  uint32
1592  	smcDPassiveOpened uint32
1593  	smcDConnClosed    uint32
1594  	smcDInSegs        uint64
1595  	smcDOutSegs       uint64
1596  	smcDInRsts        uint32
1597  	smcDOutRsts       uint32
1598  }
1599  
1600  type nwmConnEntry struct {
1601  	ident             uint32
1602  	local             [28]byte // union of sockaddr4 and sockaddr6
1603  	remote            [28]byte // union of sockaddr4 and sockaddr6
1604  	startTime         [8]byte  // uint64, changed to prevent padding from being inserted
1605  	lastActivity      [8]byte  // uint64
1606  	bytesIn           [8]byte  // uint64
1607  	bytesOut          [8]byte  // uint64
1608  	inSegs            [8]byte  // uint64
1609  	outSegs           [8]byte  // uint64
1610  	state             uint16
1611  	activeOpen        byte
1612  	flag01            byte
1613  	outBuffered       uint32
1614  	inBuffered        uint32
1615  	maxSndWnd         uint32
1616  	reXmtCount        uint32
1617  	congestionWnd     uint32
1618  	ssThresh          uint32
1619  	roundTripTime     uint32
1620  	roundTripVar      uint32
1621  	sendMSS           uint32
1622  	sndWnd            uint32
1623  	rcvBufSize        uint32
1624  	sndBufSize        uint32
1625  	outOfOrderCount   uint32
1626  	lcl0WindowCount   uint32
1627  	rmt0WindowCount   uint32
1628  	dupacks           uint32
1629  	flag02            byte
1630  	sockOpt6Cont      byte
1631  	asid              uint16
1632  	resourceName      [8]byte
1633  	resourceId        uint32
1634  	subtask           uint32
1635  	sockOpt           byte
1636  	sockOpt6          byte
1637  	clusterConnFlag   byte
1638  	proto             byte
1639  	targetAppl        [8]byte
1640  	luName            [8]byte
1641  	clientUserId      [8]byte
1642  	logMode           [8]byte
1643  	timeStamp         uint32
1644  	timeStampAge      uint32
1645  	serverResourceId  uint32
1646  	intfName          [16]byte
1647  	ttlsStatPol       byte
1648  	ttlsStatConn      byte
1649  	ttlsSSLProt       uint16
1650  	ttlsNegCiph       [2]byte
1651  	ttlsSecType       byte
1652  	ttlsFIPS140Mode   byte
1653  	ttlsUserID        [8]byte
1654  	applData          [40]byte
1655  	inOldestTime      [8]byte // uint64
1656  	outOldestTime     [8]byte // uint64
1657  	tcpTrustedPartner byte
1658  	_                 [3]byte
1659  	bulkDataIntfName  [16]byte
1660  	ttlsNegCiph4      [4]byte
1661  	smcReason         uint32
1662  	lclSMCLinkId      uint32
1663  	rmtSMCLinkId      uint32
1664  	smcStatus         byte
1665  	smcFlags          byte
1666  	_                 [2]byte
1667  	rcvWnd            uint32
1668  	lclSMCBufSz       uint32
1669  	rmtSMCBufSz       uint32
1670  	ttlsSessID        [32]byte
1671  	ttlsSessIDLen     int16
1672  	_                 [1]byte
1673  	smcDStatus        byte
1674  	smcDReason        uint32
1675  }
1676  
1677  var svcNameTable [][]byte = [][]byte{
1678  	[]byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"), // svc_EZBNMIF4
1679  }
1680  
1681  const (
1682  	svc_EZBNMIF4 = 0
1683  )
1684  
1685  func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
1686  	jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40") // "*"
1687  	responseBuffer := [4096]byte{0}
1688  	var bufferAlet, reasonCode uint32 = 0, 0
1689  	var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
1690  
1691  	dsa := [18]uint64{0}
1692  	var argv [7]unsafe.Pointer
1693  	argv[0] = unsafe.Pointer(&jobname[0])
1694  	argv[1] = unsafe.Pointer(&responseBuffer[0])
1695  	argv[2] = unsafe.Pointer(&bufferAlet)
1696  	argv[3] = unsafe.Pointer(&bufferLen)
1697  	argv[4] = unsafe.Pointer(&returnValue)
1698  	argv[5] = unsafe.Pointer(&returnCode)
1699  	argv[6] = unsafe.Pointer(&reasonCode)
1700  
1701  	request := (*struct {
1702  		header nwmHeader
1703  		filter nwmFilter
1704  	})(unsafe.Pointer(&responseBuffer[0]))
1705  
1706  	EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
1707  	if EZBNMIF4 == nil {
1708  		return nil, errnoErr(EINVAL)
1709  	}
1710  
1711  	// GetGlobalStats EZBNMIF4 call
1712  	request.header.ident = nwmHeaderIdentifier
1713  	request.header.length = uint32(unsafe.Sizeof(request.header))
1714  	request.header.version = nwmCurrentVer
1715  	request.header.nwmType = nwmGlobalStatsType
1716  	request.header.options = 0x80000000
1717  
1718  	svcCall(EZBNMIF4, &argv[0], &dsa[0])
1719  
1720  	// outputDesc field is filled by EZBNMIF4 on success
1721  	if returnCode != 0 || request.header.outputDesc.offset == 0 {
1722  		return nil, errnoErr(EINVAL)
1723  	}
1724  
1725  	// Check that EZBNMIF4 returned a nwmRecHeader
1726  	recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
1727  	if recHeader.ident != nwmRecHeaderIdentifier {
1728  		return nil, errnoErr(EINVAL)
1729  	}
1730  
1731  	// Parse nwmTriplets to get offsets of returned entries
1732  	var sections []*uint64
1733  	var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
1734  	for i := uint32(0); i < uint32(recHeader.number); i++ {
1735  		offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
1736  		sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
1737  		for j := uint32(0); j < sectionDesc.number; j++ {
1738  			offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
1739  			sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
1740  		}
1741  	}
1742  
1743  	// Find nwmTCPStatsEntry in returned entries
1744  	var tcpStats *nwmTCPStatsEntry = nil
1745  	for _, ptr := range sections {
1746  		switch *ptr {
1747  		case nwmTCPStatsIdentifier:
1748  			if tcpStats != nil {
1749  				return nil, errnoErr(EINVAL)
1750  			}
1751  			tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
1752  		case nwmIPStatsIdentifier:
1753  		case nwmIPGStatsIdentifier:
1754  		case nwmUDPStatsIdentifier:
1755  		case nwmICMPGStatsEntry:
1756  		case nwmICMPTStatsEntry:
1757  		default:
1758  			return nil, errnoErr(EINVAL)
1759  		}
1760  	}
1761  	if tcpStats == nil {
1762  		return nil, errnoErr(EINVAL)
1763  	}
1764  
1765  	// GetConnectionDetail EZBNMIF4 call
1766  	responseBuffer = [4096]byte{0}
1767  	dsa = [18]uint64{0}
1768  	bufferAlet, reasonCode = 0, 0
1769  	bufferLen, returnValue, returnCode = 4096, 0, 0
1770  	nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process
1771  	nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
1772  	argv[0] = unsafe.Pointer(uintptr(*nameptr))
1773  
1774  	request.header.ident = nwmHeaderIdentifier
1775  	request.header.length = uint32(unsafe.Sizeof(request.header))
1776  	request.header.version = nwmCurrentVer
1777  	request.header.nwmType = nwmTCPConnType
1778  	request.header.options = 0x80000000
1779  
1780  	request.filter.ident = nwmFilterIdentifier
1781  
1782  	var localSockaddr RawSockaddrAny
1783  	socklen := _Socklen(SizeofSockaddrAny)
1784  	err := getsockname(fd, &localSockaddr, &socklen)
1785  	if err != nil {
1786  		return nil, errnoErr(EINVAL)
1787  	}
1788  	if localSockaddr.Addr.Family == AF_INET {
1789  		localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
1790  		localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
1791  		localSockFilter.Family = AF_INET
1792  		var i int
1793  		for i = 0; i < 4; i++ {
1794  			if localSockaddr.Addr[i] != 0 {
1795  				break
1796  			}
1797  		}
1798  		if i != 4 {
1799  			request.filter.flags |= nwmFilterLclAddrMask
1800  			for i = 0; i < 4; i++ {
1801  				localSockFilter.Addr[i] = localSockaddr.Addr[i]
1802  			}
1803  		}
1804  		if localSockaddr.Port != 0 {
1805  			request.filter.flags |= nwmFilterLclPortMask
1806  			localSockFilter.Port = localSockaddr.Port
1807  		}
1808  	} else if localSockaddr.Addr.Family == AF_INET6 {
1809  		localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
1810  		localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
1811  		localSockFilter.Family = AF_INET6
1812  		var i int
1813  		for i = 0; i < 16; i++ {
1814  			if localSockaddr.Addr[i] != 0 {
1815  				break
1816  			}
1817  		}
1818  		if i != 16 {
1819  			request.filter.flags |= nwmFilterLclAddrMask
1820  			for i = 0; i < 16; i++ {
1821  				localSockFilter.Addr[i] = localSockaddr.Addr[i]
1822  			}
1823  		}
1824  		if localSockaddr.Port != 0 {
1825  			request.filter.flags |= nwmFilterLclPortMask
1826  			localSockFilter.Port = localSockaddr.Port
1827  		}
1828  	}
1829  
1830  	svcCall(EZBNMIF4, &argv[0], &dsa[0])
1831  
1832  	// outputDesc field is filled by EZBNMIF4 on success
1833  	if returnCode != 0 || request.header.outputDesc.offset == 0 {
1834  		return nil, errnoErr(EINVAL)
1835  	}
1836  
1837  	// Check that EZBNMIF4 returned a nwmConnEntry
1838  	conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
1839  	if conn.ident != nwmTCPConnIdentifier {
1840  		return nil, errnoErr(EINVAL)
1841  	}
1842  
1843  	// Copy data from the returned data structures into tcpInfo
1844  	// Stats from nwmConnEntry are specific to that connection.
1845  	// Stats from nwmTCPStatsEntry are global (to the interface?)
1846  	// Fields may not be an exact match. Some fields have no equivalent.
1847  	var tcpinfo TCPInfo
1848  	tcpinfo.State = uint8(conn.state)
1849  	tcpinfo.Ca_state = 0 // dummy
1850  	tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
1851  	tcpinfo.Probes = uint8(tcpStats.outWinProbes)
1852  	tcpinfo.Backoff = 0 // dummy
1853  	tcpinfo.Options = 0 // dummy
1854  	tcpinfo.Rto = tcpStats.retransTimeouts
1855  	tcpinfo.Ato = tcpStats.outDelayAcks
1856  	tcpinfo.Snd_mss = conn.sendMSS
1857  	tcpinfo.Rcv_mss = conn.sendMSS // dummy
1858  	tcpinfo.Unacked = 0            // dummy
1859  	tcpinfo.Sacked = 0             // dummy
1860  	tcpinfo.Lost = 0               // dummy
1861  	tcpinfo.Retrans = conn.reXmtCount
1862  	tcpinfo.Fackets = 0 // dummy
1863  	tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
1864  	tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
1865  	tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
1866  	tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
1867  	tcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate
1868  	tcpinfo.Rcv_ssthresh = conn.ssThresh
1869  	tcpinfo.Rtt = conn.roundTripTime
1870  	tcpinfo.Rttvar = conn.roundTripVar
1871  	tcpinfo.Snd_ssthresh = conn.ssThresh // dummy
1872  	tcpinfo.Snd_cwnd = conn.congestionWnd
1873  	tcpinfo.Advmss = conn.sendMSS        // dummy
1874  	tcpinfo.Reordering = 0               // dummy
1875  	tcpinfo.Rcv_rtt = conn.roundTripTime // dummy
1876  	tcpinfo.Rcv_space = conn.sendMSS     // dummy
1877  	tcpinfo.Total_retrans = conn.reXmtCount
1878  
1879  	svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
1880  
1881  	return &tcpinfo, nil
1882  }
1883  
1884  // GetsockoptString returns the string value of the socket option opt for the
1885  // socket associated with fd at the given socket level.
1886  func GetsockoptString(fd, level, opt int) (string, error) {
1887  	buf := make([]byte, 256)
1888  	vallen := _Socklen(len(buf))
1889  	err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1890  	if err != nil {
1891  		return "", err
1892  	}
1893  
1894  	return ByteSliceToString(buf[:vallen]), nil
1895  }
1896  
1897  func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
1898  	var msg Msghdr
1899  	var rsa RawSockaddrAny
1900  	msg.Name = (*byte)(unsafe.Pointer(&rsa))
1901  	msg.Namelen = SizeofSockaddrAny
1902  	var iov Iovec
1903  	if len(p) > 0 {
1904  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
1905  		iov.SetLen(len(p))
1906  	}
1907  	var dummy byte
1908  	if len(oob) > 0 {
1909  		// receive at least one normal byte
1910  		if len(p) == 0 {
1911  			iov.Base = &dummy
1912  			iov.SetLen(1)
1913  		}
1914  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
1915  		msg.SetControllen(len(oob))
1916  	}
1917  	msg.Iov = &iov
1918  	msg.Iovlen = 1
1919  	if n, err = recvmsg(fd, &msg, flags); err != nil {
1920  		return
1921  	}
1922  	oobn = int(msg.Controllen)
1923  	recvflags = int(msg.Flags)
1924  	// source address is only specified if the socket is unconnected
1925  	if rsa.Addr.Family != AF_UNSPEC {
1926  		// TODO(neeilan): Remove 0 arg added to get this compiling on z/OS
1927  		from, err = anyToSockaddr(0, &rsa)
1928  	}
1929  	return
1930  }
1931  
1932  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
1933  	_, err = SendmsgN(fd, p, oob, to, flags)
1934  	return
1935  }
1936  
1937  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
1938  	var ptr unsafe.Pointer
1939  	var salen _Socklen
1940  	if to != nil {
1941  		var err error
1942  		ptr, salen, err = to.sockaddr()
1943  		if err != nil {
1944  			return 0, err
1945  		}
1946  	}
1947  	var msg Msghdr
1948  	msg.Name = (*byte)(unsafe.Pointer(ptr))
1949  	msg.Namelen = int32(salen)
1950  	var iov Iovec
1951  	if len(p) > 0 {
1952  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
1953  		iov.SetLen(len(p))
1954  	}
1955  	var dummy byte
1956  	if len(oob) > 0 {
1957  		// send at least one normal byte
1958  		if len(p) == 0 {
1959  			iov.Base = &dummy
1960  			iov.SetLen(1)
1961  		}
1962  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
1963  		msg.SetControllen(len(oob))
1964  	}
1965  	msg.Iov = &iov
1966  	msg.Iovlen = 1
1967  	if n, err = sendmsg(fd, &msg, flags); err != nil {
1968  		return 0, err
1969  	}
1970  	if len(oob) > 0 && len(p) == 0 {
1971  		n = 0
1972  	}
1973  	return n, nil
1974  }
1975  
1976  func Opendir(name string) (uintptr, error) {
1977  	p, err := BytePtrFromString(name)
1978  	if err != nil {
1979  		return 0, err
1980  	}
1981  	err = nil
1982  	runtime.EnterSyscall()
1983  	dir, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___OPENDIR_A<<4, uintptr(unsafe.Pointer(p)))
1984  	runtime.ExitSyscall()
1985  	runtime.KeepAlive(unsafe.Pointer(p))
1986  	if dir == 0 {
1987  		err = errnoErr2(e1, e2)
1988  	}
1989  	return dir, err
1990  }
1991  
1992  // clearsyscall.Errno resets the errno value to 0.
1993  func clearErrno()
1994  
1995  func Closedir(dir uintptr) error {
1996  	runtime.EnterSyscall()
1997  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSEDIR<<4, dir)
1998  	runtime.ExitSyscall()
1999  	if r0 != 0 {
2000  		return errnoErr2(e1, e2)
2001  	}
2002  	return nil
2003  }
2004  
2005  func Seekdir(dir uintptr, pos int) {
2006  	runtime.EnterSyscall()
2007  	CallLeFuncWithErr(GetZosLibVec()+SYS_SEEKDIR<<4, dir, uintptr(pos))
2008  	runtime.ExitSyscall()
2009  }
2010  
2011  func Telldir(dir uintptr) (int, error) {
2012  	p, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TELLDIR<<4, dir)
2013  	pos := int(p)
2014  	if int64(p) == -1 {
2015  		return pos, errnoErr2(e1, e2)
2016  	}
2017  	return pos, nil
2018  }
2019  
2020  // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
2021  func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
2022  	// struct flock is packed on z/OS. We can't emulate that in Go so
2023  	// instead we pack it here.
2024  	var flock [24]byte
2025  	*(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
2026  	*(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
2027  	*(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
2028  	*(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
2029  	*(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
2030  	runtime.EnterSyscall()
2031  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
2032  	runtime.ExitSyscall()
2033  	lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
2034  	lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
2035  	lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
2036  	lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
2037  	lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
2038  	if r0 == 0 {
2039  		return nil
2040  	}
2041  	return errnoErr2(e1, e2)
2042  }
2043  
2044  func impl_Flock(fd int, how int) (err error) {
2045  	runtime.EnterSyscall()
2046  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FLOCK<<4, uintptr(fd), uintptr(how))
2047  	runtime.ExitSyscall()
2048  	if int64(r0) == -1 {
2049  		err = errnoErr2(e1, e2)
2050  	}
2051  	return
2052  }
2053  
2054  //go:nosplit
2055  func get_FlockAddr() *(func(fd int, how int) (err error))
2056  
2057  var Flock = enter_Flock
2058  
2059  func validFlock(fp uintptr) bool {
2060  	if funcptrtest(GetZosLibVec()+SYS_FLOCK<<4, "") == 0 {
2061  		if name, err := getLeFuncName(GetZosLibVec() + SYS_FLOCK<<4); err == nil {
2062  			return name == "flock"
2063  		}
2064  	}
2065  	return false
2066  }
2067  
2068  func enter_Flock(fd int, how int) (err error) {
2069  	funcref := get_FlockAddr()
2070  	if validFlock(GetZosLibVec() + SYS_FLOCK<<4) {
2071  		*funcref = impl_Flock
2072  	} else {
2073  		*funcref = legacyFlock
2074  	}
2075  	return (*funcref)(fd, how)
2076  }
2077  
2078  func legacyFlock(fd int, how int) error {
2079  
2080  	var flock_type int16
2081  	var fcntl_cmd int
2082  
2083  	switch how {
2084  	case LOCK_SH | LOCK_NB:
2085  		flock_type = F_RDLCK
2086  		fcntl_cmd = F_SETLK
2087  	case LOCK_EX | LOCK_NB:
2088  		flock_type = F_WRLCK
2089  		fcntl_cmd = F_SETLK
2090  	case LOCK_EX:
2091  		flock_type = F_WRLCK
2092  		fcntl_cmd = F_SETLKW
2093  	case LOCK_UN:
2094  		flock_type = F_UNLCK
2095  		fcntl_cmd = F_SETLKW
2096  	default:
2097  	}
2098  
2099  	flock := Flock_t{
2100  		Type:   int16(flock_type),
2101  		Whence: int16(0),
2102  		Start:  int64(0),
2103  		Len:    int64(0),
2104  		Pid:    int32(Getppid()),
2105  	}
2106  
2107  	err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
2108  	return err
2109  }
2110  
2111  func Mlock(b []byte) (err error) {
2112  	runtime.EnterSyscall()
2113  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2114  	runtime.ExitSyscall()
2115  	if r0 != 0 {
2116  		err = errnoErr2(e1, e2)
2117  	}
2118  	return
2119  }
2120  
2121  func Mlock2(b []byte, flags int) (err error) {
2122  	runtime.EnterSyscall()
2123  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2124  	runtime.ExitSyscall()
2125  	if r0 != 0 {
2126  		err = errnoErr2(e1, e2)
2127  	}
2128  	return
2129  }
2130  
2131  func Mlockall(flags int) (err error) {
2132  	runtime.EnterSyscall()
2133  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2134  	runtime.ExitSyscall()
2135  	if r0 != 0 {
2136  		err = errnoErr2(e1, e2)
2137  	}
2138  	return
2139  }
2140  
2141  func Munlock(b []byte) (err error) {
2142  	runtime.EnterSyscall()
2143  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
2144  	runtime.ExitSyscall()
2145  	if r0 != 0 {
2146  		err = errnoErr2(e1, e2)
2147  	}
2148  	return
2149  }
2150  
2151  func Munlockall() (err error) {
2152  	runtime.EnterSyscall()
2153  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
2154  	runtime.ExitSyscall()
2155  	if r0 != 0 {
2156  		err = errnoErr2(e1, e2)
2157  	}
2158  	return
2159  }
2160  
2161  func ClockGettime(clockid int32, ts *Timespec) error {
2162  
2163  	var ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise
2164  	var nsec_per_sec int64 = 1000000000
2165  
2166  	if ts == nil {
2167  		return EFAULT
2168  	}
2169  	if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
2170  		var nanotime int64 = runtime.Nanotime1()
2171  		ts.Sec = nanotime / nsec_per_sec
2172  		ts.Nsec = nanotime % nsec_per_sec
2173  	} else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
2174  		var tm Tms
2175  		_, err := Times(&tm)
2176  		if err != nil {
2177  			return EFAULT
2178  		}
2179  		ts.Sec = int64(tm.Utime / ticks_per_sec)
2180  		ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
2181  	} else {
2182  		return EINVAL
2183  	}
2184  	return nil
2185  }
2186  
2187  // Chtag
2188  
2189  //go:nosplit
2190  func get_ChtagAddr() *(func(path string, ccsid uint64, textbit uint64) error)
2191  
2192  var Chtag = enter_Chtag
2193  
2194  func enter_Chtag(path string, ccsid uint64, textbit uint64) error {
2195  	funcref := get_ChtagAddr()
2196  	if validSetxattr() {
2197  		*funcref = impl_Chtag
2198  	} else {
2199  		*funcref = legacy_Chtag
2200  	}
2201  	return (*funcref)(path, ccsid, textbit)
2202  }
2203  
2204  func legacy_Chtag(path string, ccsid uint64, textbit uint64) error {
2205  	tag := ccsid<<16 | textbit<<15
2206  	var tag_buff [8]byte
2207  	DecodeData(tag_buff[:], 8, tag)
2208  	return Setxattr(path, "filetag", tag_buff[:], XATTR_REPLACE)
2209  }
2210  
2211  func impl_Chtag(path string, ccsid uint64, textbit uint64) error {
2212  	tag := ccsid<<16 | textbit<<15
2213  	var tag_buff [4]byte
2214  	DecodeData(tag_buff[:], 4, tag)
2215  	return Setxattr(path, "system.filetag", tag_buff[:], XATTR_REPLACE)
2216  }
2217  
2218  // End of Chtag
2219  
2220  // Nanosleep
2221  
2222  //go:nosplit
2223  func get_NanosleepAddr() *(func(time *Timespec, leftover *Timespec) error)
2224  
2225  var Nanosleep = enter_Nanosleep
2226  
2227  func enter_Nanosleep(time *Timespec, leftover *Timespec) error {
2228  	funcref := get_NanosleepAddr()
2229  	if funcptrtest(GetZosLibVec()+SYS_NANOSLEEP<<4, "") == 0 {
2230  		*funcref = impl_Nanosleep
2231  	} else {
2232  		*funcref = legacyNanosleep
2233  	}
2234  	return (*funcref)(time, leftover)
2235  }
2236  
2237  func impl_Nanosleep(time *Timespec, leftover *Timespec) error {
2238  	runtime.EnterSyscall()
2239  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_NANOSLEEP<<4, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)))
2240  	runtime.ExitSyscall()
2241  	if int64(r0) == -1 {
2242  		return errnoErr2(e1, e2)
2243  	}
2244  	return nil
2245  }
2246  
2247  func legacyNanosleep(time *Timespec, leftover *Timespec) error {
2248  	t0 := runtime.Nanotime1()
2249  	var secrem uint32
2250  	var nsecrem uint32
2251  	total := time.Sec*1000000000 + time.Nsec
2252  	elapsed := runtime.Nanotime1() - t0
2253  	var rv int32
2254  	var rc int32
2255  	var err error
2256  	// repeatedly sleep for 1 second until less than 1 second left
2257  	for total-elapsed > 1000000000 {
2258  		rv, rc, _ = BpxCondTimedWait(uint32(1), uint32(0), uint32(CW_CONDVAR), &secrem, &nsecrem)
2259  		if rv != 0 && rc != 112 { // 112 is EAGAIN
2260  			if leftover != nil && rc == 120 { // 120 is EINTR
2261  				leftover.Sec = int64(secrem)
2262  				leftover.Nsec = int64(nsecrem)
2263  			}
2264  			err = Errno(rc)
2265  			return err
2266  		}
2267  		elapsed = runtime.Nanotime1() - t0
2268  	}
2269  	// sleep the remainder
2270  	if total > elapsed {
2271  		rv, rc, _ = BpxCondTimedWait(uint32(0), uint32(total-elapsed), uint32(CW_CONDVAR), &secrem, &nsecrem)
2272  	}
2273  	if leftover != nil && rc == 120 {
2274  		leftover.Sec = int64(secrem)
2275  		leftover.Nsec = int64(nsecrem)
2276  	}
2277  	if rv != 0 && rc != 112 {
2278  		err = Errno(rc)
2279  	}
2280  	return err
2281  }
2282  
2283  // End of Nanosleep
2284  
2285  var (
2286  	Stdin  = 0
2287  	Stdout = 1
2288  	Stderr = 2
2289  )
2290  
2291  // Do the interface allocations only once for common
2292  // Errno values.
2293  var (
2294  	errEAGAIN error = syscall.EAGAIN
2295  	errEINVAL error = syscall.EINVAL
2296  	errENOENT error = syscall.ENOENT
2297  )
2298  
2299  var ZosTraceLevel int
2300  var ZosTracefile *os.File
2301  
2302  var (
2303  	signalNameMapOnce sync.Once
2304  	signalNameMap     map[string]syscall.Signal
2305  )
2306  
2307  // errnoErr returns common boxed Errno values, to prevent
2308  // allocations at runtime.
2309  func errnoErr(e Errno) error {
2310  	switch e {
2311  	case 0:
2312  		return nil
2313  	case EAGAIN:
2314  		return errEAGAIN
2315  	case EINVAL:
2316  		return errEINVAL
2317  	case ENOENT:
2318  		return errENOENT
2319  	}
2320  	return e
2321  }
2322  
2323  var reg *regexp.Regexp
2324  
2325  // enhanced with zos specific errno2
2326  func errnoErr2(e Errno, e2 uintptr) error {
2327  	switch e {
2328  	case 0:
2329  		return nil
2330  	case EAGAIN:
2331  		return errEAGAIN
2332  		/*
2333  			Allow the retrieval of errno2 for EINVAL and ENOENT on zos
2334  				case EINVAL:
2335  					return errEINVAL
2336  				case ENOENT:
2337  					return errENOENT
2338  		*/
2339  	}
2340  	if ZosTraceLevel > 0 {
2341  		var name string
2342  		if reg == nil {
2343  			reg = regexp.MustCompile("(^unix\\.[^/]+$|.*\\/unix\\.[^/]+$)")
2344  		}
2345  		i := 1
2346  		pc, file, line, ok := runtime.Caller(i)
2347  		if ok {
2348  			name = runtime.FuncForPC(pc).Name()
2349  		}
2350  		for ok && reg.MatchString(runtime.FuncForPC(pc).Name()) {
2351  			i += 1
2352  			pc, file, line, ok = runtime.Caller(i)
2353  		}
2354  		if ok {
2355  			if ZosTracefile == nil {
2356  				ZosConsolePrintf("From %s:%d\n", file, line)
2357  				ZosConsolePrintf("%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
2358  			} else {
2359  				fmt.Fprintf(ZosTracefile, "From %s:%d\n", file, line)
2360  				fmt.Fprintf(ZosTracefile, "%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
2361  			}
2362  		} else {
2363  			if ZosTracefile == nil {
2364  				ZosConsolePrintf("%s (errno2=0x%x)\n", e.Error(), e2)
2365  			} else {
2366  				fmt.Fprintf(ZosTracefile, "%s (errno2=0x%x)\n", e.Error(), e2)
2367  			}
2368  		}
2369  	}
2370  	return e
2371  }
2372  
2373  // ErrnoName returns the error name for error number e.
2374  func ErrnoName(e Errno) string {
2375  	i := sort.Search(len(errorList), func(i int) bool {
2376  		return errorList[i].num >= e
2377  	})
2378  	if i < len(errorList) && errorList[i].num == e {
2379  		return errorList[i].name
2380  	}
2381  	return ""
2382  }
2383  
2384  // SignalName returns the signal name for signal number s.
2385  func SignalName(s syscall.Signal) string {
2386  	i := sort.Search(len(signalList), func(i int) bool {
2387  		return signalList[i].num >= s
2388  	})
2389  	if i < len(signalList) && signalList[i].num == s {
2390  		return signalList[i].name
2391  	}
2392  	return ""
2393  }
2394  
2395  // SignalNum returns the syscall.Signal for signal named s,
2396  // or 0 if a signal with such name is not found.
2397  // The signal name should start with "SIG".
2398  func SignalNum(s string) syscall.Signal {
2399  	signalNameMapOnce.Do(func() {
2400  		signalNameMap = make(map[string]syscall.Signal, len(signalList))
2401  		for _, signal := range signalList {
2402  			signalNameMap[signal.name] = signal.num
2403  		}
2404  	})
2405  	return signalNameMap[s]
2406  }
2407  
2408  // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
2409  func clen(n []byte) int {
2410  	i := bytes.IndexByte(n, 0)
2411  	if i == -1 {
2412  		i = len(n)
2413  	}
2414  	return i
2415  }
2416  
2417  // Mmap manager, for use by operating system-specific implementations.
2418  
2419  type mmapper struct {
2420  	sync.Mutex
2421  	active map[*byte][]byte // active mappings; key is last byte in mapping
2422  	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
2423  	munmap func(addr uintptr, length uintptr) error
2424  }
2425  
2426  func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
2427  	if length <= 0 {
2428  		return nil, EINVAL
2429  	}
2430  
2431  	// Set __MAP_64 by default
2432  	flags |= __MAP_64
2433  
2434  	// Map the requested memory.
2435  	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
2436  	if errno != nil {
2437  		return nil, errno
2438  	}
2439  
2440  	// Slice memory layout
2441  	var sl = struct {
2442  		addr uintptr
2443  		len  int
2444  		cap  int
2445  	}{addr, length, length}
2446  
2447  	// Use unsafe to turn sl into a []byte.
2448  	b := *(*[]byte)(unsafe.Pointer(&sl))
2449  
2450  	// Register mapping in m and return it.
2451  	p := &b[cap(b)-1]
2452  	m.Lock()
2453  	defer m.Unlock()
2454  	m.active[p] = b
2455  	return b, nil
2456  }
2457  
2458  func (m *mmapper) Munmap(data []byte) (err error) {
2459  	if len(data) == 0 || len(data) != cap(data) {
2460  		return EINVAL
2461  	}
2462  
2463  	// Find the base of the mapping.
2464  	p := &data[cap(data)-1]
2465  	m.Lock()
2466  	defer m.Unlock()
2467  	b := m.active[p]
2468  	if b == nil || &b[0] != &data[0] {
2469  		return EINVAL
2470  	}
2471  
2472  	// Unmap the memory and update m.
2473  	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
2474  		return errno
2475  	}
2476  	delete(m.active, p)
2477  	return nil
2478  }
2479  
2480  func Read(fd int, p []byte) (n int, err error) {
2481  	n, err = read(fd, p)
2482  	if raceenabled {
2483  		if n > 0 {
2484  			raceWriteRange(unsafe.Pointer(&p[0]), n)
2485  		}
2486  		if err == nil {
2487  			raceAcquire(unsafe.Pointer(&ioSync))
2488  		}
2489  	}
2490  	return
2491  }
2492  
2493  func Write(fd int, p []byte) (n int, err error) {
2494  	if raceenabled {
2495  		raceReleaseMerge(unsafe.Pointer(&ioSync))
2496  	}
2497  	n, err = write(fd, p)
2498  	if raceenabled && n > 0 {
2499  		raceReadRange(unsafe.Pointer(&p[0]), n)
2500  	}
2501  	return
2502  }
2503  
2504  // For testing: clients can set this flag to force
2505  // creation of IPv6 sockets to return EAFNOSUPPORT.
2506  var SocketDisableIPv6 bool
2507  
2508  // Sockaddr represents a socket address.
2509  type Sockaddr interface {
2510  	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
2511  }
2512  
2513  // SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
2514  type SockaddrInet4 struct {
2515  	Port int
2516  	Addr [4]byte
2517  	raw  RawSockaddrInet4
2518  }
2519  
2520  // SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
2521  type SockaddrInet6 struct {
2522  	Port   int
2523  	ZoneId uint32
2524  	Addr   [16]byte
2525  	raw    RawSockaddrInet6
2526  }
2527  
2528  // SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
2529  type SockaddrUnix struct {
2530  	Name string
2531  	raw  RawSockaddrUnix
2532  }
2533  
2534  func Bind(fd int, sa Sockaddr) (err error) {
2535  	ptr, n, err := sa.sockaddr()
2536  	if err != nil {
2537  		return err
2538  	}
2539  	return bind(fd, ptr, n)
2540  }
2541  
2542  func Connect(fd int, sa Sockaddr) (err error) {
2543  	ptr, n, err := sa.sockaddr()
2544  	if err != nil {
2545  		return err
2546  	}
2547  	return connect(fd, ptr, n)
2548  }
2549  
2550  func Getpeername(fd int) (sa Sockaddr, err error) {
2551  	var rsa RawSockaddrAny
2552  	var len _Socklen = SizeofSockaddrAny
2553  	if err = getpeername(fd, &rsa, &len); err != nil {
2554  		return
2555  	}
2556  	return anyToSockaddr(fd, &rsa)
2557  }
2558  
2559  func GetsockoptByte(fd, level, opt int) (value byte, err error) {
2560  	var n byte
2561  	vallen := _Socklen(1)
2562  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2563  	return n, err
2564  }
2565  
2566  func GetsockoptInt(fd, level, opt int) (value int, err error) {
2567  	var n int32
2568  	vallen := _Socklen(4)
2569  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2570  	return int(n), err
2571  }
2572  
2573  func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
2574  	vallen := _Socklen(4)
2575  	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
2576  	return value, err
2577  }
2578  
2579  func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
2580  	var value IPMreq
2581  	vallen := _Socklen(SizeofIPMreq)
2582  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2583  	return &value, err
2584  }
2585  
2586  func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
2587  	var value IPv6Mreq
2588  	vallen := _Socklen(SizeofIPv6Mreq)
2589  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2590  	return &value, err
2591  }
2592  
2593  func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
2594  	var value IPv6MTUInfo
2595  	vallen := _Socklen(SizeofIPv6MTUInfo)
2596  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2597  	return &value, err
2598  }
2599  
2600  func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
2601  	var value ICMPv6Filter
2602  	vallen := _Socklen(SizeofICMPv6Filter)
2603  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2604  	return &value, err
2605  }
2606  
2607  func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
2608  	var linger Linger
2609  	vallen := _Socklen(SizeofLinger)
2610  	err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
2611  	return &linger, err
2612  }
2613  
2614  func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
2615  	var tv Timeval
2616  	vallen := _Socklen(unsafe.Sizeof(tv))
2617  	err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
2618  	return &tv, err
2619  }
2620  
2621  func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
2622  	var n uint64
2623  	vallen := _Socklen(8)
2624  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2625  	return n, err
2626  }
2627  
2628  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
2629  	var rsa RawSockaddrAny
2630  	var len _Socklen = SizeofSockaddrAny
2631  	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
2632  		return
2633  	}
2634  	if rsa.Addr.Family != AF_UNSPEC {
2635  		from, err = anyToSockaddr(fd, &rsa)
2636  	}
2637  	return
2638  }
2639  
2640  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
2641  	ptr, n, err := to.sockaddr()
2642  	if err != nil {
2643  		return err
2644  	}
2645  	return sendto(fd, p, flags, ptr, n)
2646  }
2647  
2648  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
2649  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
2650  }
2651  
2652  func SetsockoptInt(fd, level, opt int, value int) (err error) {
2653  	var n = int32(value)
2654  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
2655  }
2656  
2657  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
2658  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
2659  }
2660  
2661  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
2662  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
2663  }
2664  
2665  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
2666  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
2667  }
2668  
2669  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
2670  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
2671  }
2672  
2673  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
2674  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
2675  }
2676  
2677  func SetsockoptString(fd, level, opt int, s string) (err error) {
2678  	var p unsafe.Pointer
2679  	if len(s) > 0 {
2680  		p = unsafe.Pointer(&[]byte(s)[0])
2681  	}
2682  	return setsockopt(fd, level, opt, p, uintptr(len(s)))
2683  }
2684  
2685  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
2686  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
2687  }
2688  
2689  func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
2690  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
2691  }
2692  
2693  func Socket(domain, typ, proto int) (fd int, err error) {
2694  	if domain == AF_INET6 && SocketDisableIPv6 {
2695  		return -1, EAFNOSUPPORT
2696  	}
2697  	fd, err = socket(domain, typ, proto)
2698  	return
2699  }
2700  
2701  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
2702  	var fdx [2]int32
2703  	err = socketpair(domain, typ, proto, &fdx)
2704  	if err == nil {
2705  		fd[0] = int(fdx[0])
2706  		fd[1] = int(fdx[1])
2707  	}
2708  	return
2709  }
2710  
2711  var ioSync int64
2712  
2713  func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
2714  
2715  func SetNonblock(fd int, nonblocking bool) (err error) {
2716  	flag, err := fcntl(fd, F_GETFL, 0)
2717  	if err != nil {
2718  		return err
2719  	}
2720  	if nonblocking {
2721  		flag |= O_NONBLOCK
2722  	} else {
2723  		flag &= ^O_NONBLOCK
2724  	}
2725  	_, err = fcntl(fd, F_SETFL, flag)
2726  	return err
2727  }
2728  
2729  // Exec calls execve(2), which replaces the calling executable in the process
2730  // tree. argv0 should be the full path to an executable ("/bin/ls") and the
2731  // executable name should also be the first argument in argv (["ls", "-l"]).
2732  // envv are the environment variables that should be passed to the new
2733  // process (["USER=go", "PWD=/tmp"]).
2734  func Exec(argv0 string, argv []string, envv []string) error {
2735  	return syscall.Exec(argv0, argv, envv)
2736  }
2737  
2738  func Getag(path string) (ccsid uint16, flag uint16, err error) {
2739  	var val [8]byte
2740  	sz, err := Getxattr(path, "ccsid", val[:])
2741  	if err != nil {
2742  		return
2743  	}
2744  	ccsid = uint16(EncodeData(val[0:sz]))
2745  	sz, err = Getxattr(path, "flags", val[:])
2746  	if err != nil {
2747  		return
2748  	}
2749  	flag = uint16(EncodeData(val[0:sz]) >> 15)
2750  	return
2751  }
2752  
2753  // Mount begin
2754  func impl_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2755  	var _p0 *byte
2756  	_p0, err = BytePtrFromString(source)
2757  	if err != nil {
2758  		return
2759  	}
2760  	var _p1 *byte
2761  	_p1, err = BytePtrFromString(target)
2762  	if err != nil {
2763  		return
2764  	}
2765  	var _p2 *byte
2766  	_p2, err = BytePtrFromString(fstype)
2767  	if err != nil {
2768  		return
2769  	}
2770  	var _p3 *byte
2771  	_p3, err = BytePtrFromString(data)
2772  	if err != nil {
2773  		return
2774  	}
2775  	runtime.EnterSyscall()
2776  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MOUNT1_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(_p3)))
2777  	runtime.ExitSyscall()
2778  	if int64(r0) == -1 {
2779  		err = errnoErr2(e1, e2)
2780  	}
2781  	return
2782  }
2783  
2784  //go:nosplit
2785  func get_MountAddr() *(func(source string, target string, fstype string, flags uintptr, data string) (err error))
2786  
2787  var Mount = enter_Mount
2788  
2789  func enter_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2790  	funcref := get_MountAddr()
2791  	if validMount() {
2792  		*funcref = impl_Mount
2793  	} else {
2794  		*funcref = legacyMount
2795  	}
2796  	return (*funcref)(source, target, fstype, flags, data)
2797  }
2798  
2799  func legacyMount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2800  	if needspace := 8 - len(fstype); needspace <= 0 {
2801  		fstype = fstype[0:8]
2802  	} else {
2803  		fstype += "        "[0:needspace]
2804  	}
2805  	return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
2806  }
2807  
2808  func validMount() bool {
2809  	if funcptrtest(GetZosLibVec()+SYS___MOUNT1_A<<4, "") == 0 {
2810  		if name, err := getLeFuncName(GetZosLibVec() + SYS___MOUNT1_A<<4); err == nil {
2811  			return name == "__mount1_a"
2812  		}
2813  	}
2814  	return false
2815  }
2816  
2817  // Mount end
2818  
2819  // Unmount begin
2820  func impl_Unmount(target string, flags int) (err error) {
2821  	var _p0 *byte
2822  	_p0, err = BytePtrFromString(target)
2823  	if err != nil {
2824  		return
2825  	}
2826  	runtime.EnterSyscall()
2827  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UMOUNT2_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(flags))
2828  	runtime.ExitSyscall()
2829  	if int64(r0) == -1 {
2830  		err = errnoErr2(e1, e2)
2831  	}
2832  	return
2833  }
2834  
2835  //go:nosplit
2836  func get_UnmountAddr() *(func(target string, flags int) (err error))
2837  
2838  var Unmount = enter_Unmount
2839  
2840  func enter_Unmount(target string, flags int) (err error) {
2841  	funcref := get_UnmountAddr()
2842  	if funcptrtest(GetZosLibVec()+SYS___UMOUNT2_A<<4, "") == 0 {
2843  		*funcref = impl_Unmount
2844  	} else {
2845  		*funcref = legacyUnmount
2846  	}
2847  	return (*funcref)(target, flags)
2848  }
2849  
2850  func legacyUnmount(name string, mtm int) (err error) {
2851  	// mountpoint is always a full path and starts with a '/'
2852  	// check if input string is not a mountpoint but a filesystem name
2853  	if name[0] != '/' {
2854  		return unmount_LE(name, mtm)
2855  	}
2856  	// treat name as mountpoint
2857  	b2s := func(arr []byte) string {
2858  		var str string
2859  		for i := 0; i < len(arr); i++ {
2860  			if arr[i] == 0 {
2861  				str = string(arr[:i])
2862  				break
2863  			}
2864  		}
2865  		return str
2866  	}
2867  	var buffer struct {
2868  		header W_Mnth
2869  		fsinfo [64]W_Mntent
2870  	}
2871  	fs_count, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
2872  	if err == nil {
2873  		err = EINVAL
2874  		for i := 0; i < fs_count; i++ {
2875  			if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
2876  				err = unmount_LE(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
2877  				break
2878  			}
2879  		}
2880  	} else if fs_count == 0 {
2881  		err = EINVAL
2882  	}
2883  	return err
2884  }
2885  
2886  // Unmount end
2887  
2888  func direntIno(buf []byte) (uint64, bool) {
2889  	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
2890  }
2891  
2892  func direntReclen(buf []byte) (uint64, bool) {
2893  	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
2894  }
2895  
2896  func direntNamlen(buf []byte) (uint64, bool) {
2897  	reclen, ok := direntReclen(buf)
2898  	if !ok {
2899  		return 0, false
2900  	}
2901  	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
2902  }
2903  
2904  func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
2905  	var d Dirent
2906  
2907  	d.Ino = uint64(dirent.Ino)
2908  	offset, err := Telldir(dir)
2909  	if err != nil {
2910  		return d, err
2911  	}
2912  
2913  	d.Off = int64(offset)
2914  	s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
2915  	copy(d.Name[:], s)
2916  
2917  	d.Reclen = uint16(24 + len(d.NameString()))
2918  	var st Stat_t
2919  	path = path + "/" + s
2920  	err = Lstat(path, &st)
2921  	if err != nil {
2922  		return d, err
2923  	}
2924  
2925  	d.Type = uint8(st.Mode >> 24)
2926  	return d, err
2927  }
2928  
2929  func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
2930  	// Simulation of Getdirentries port from the Darwin implementation.
2931  	// COMMENTS FROM DARWIN:
2932  	// It's not the full required semantics, but should handle the case
2933  	// of calling Getdirentries or ReadDirent repeatedly.
2934  	// It won't handle assigning the results of lseek to *basep, or handle
2935  	// the directory being edited underfoot.
2936  
2937  	skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
2938  	if err != nil {
2939  		return 0, err
2940  	}
2941  
2942  	// Get path from fd to avoid unavailable call (fdopendir)
2943  	path, err := ZosFdToPath(fd)
2944  	if err != nil {
2945  		return 0, err
2946  	}
2947  	d, err := Opendir(path)
2948  	if err != nil {
2949  		return 0, err
2950  	}
2951  	defer Closedir(d)
2952  
2953  	var cnt int64
2954  	for {
2955  		var entryLE direntLE
2956  		var entrypLE *direntLE
2957  		e := Readdir_r(d, &entryLE, &entrypLE)
2958  		if e != nil {
2959  			return n, e
2960  		}
2961  		if entrypLE == nil {
2962  			break
2963  		}
2964  		if skip > 0 {
2965  			skip--
2966  			cnt++
2967  			continue
2968  		}
2969  
2970  		// Dirent on zos has a different structure
2971  		entry, e := direntLeToDirentUnix(&entryLE, d, path)
2972  		if e != nil {
2973  			return n, e
2974  		}
2975  
2976  		reclen := int(entry.Reclen)
2977  		if reclen > len(buf) {
2978  			// Not enough room. Return for now.
2979  			// The counter will let us know where we should start up again.
2980  			// Note: this strategy for suspending in the middle and
2981  			// restarting is O(n^2) in the length of the directory. Oh well.
2982  			break
2983  		}
2984  
2985  		// Copy entry into return buffer.
2986  		s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
2987  		copy(buf, s)
2988  
2989  		buf = buf[reclen:]
2990  		n += reclen
2991  		cnt++
2992  	}
2993  	// Set the seek offset of the input fd to record
2994  	// how many files we've already returned.
2995  	_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
2996  	if err != nil {
2997  		return n, err
2998  	}
2999  
3000  	return n, nil
3001  }
3002  
3003  func Err2ad() (eadd *int) {
3004  	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERR2AD<<4)
3005  	eadd = (*int)(unsafe.Pointer(r0))
3006  	return
3007  }
3008  
3009  func ZosConsolePrintf(format string, v ...interface{}) (int, error) {
3010  	type __cmsg struct {
3011  		_            uint16
3012  		_            [2]uint8
3013  		__msg_length uint32
3014  		__msg        uintptr
3015  		_            [4]uint8
3016  	}
3017  	msg := fmt.Sprintf(format, v...)
3018  	strptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&msg)).Data)
3019  	len := (*reflect.StringHeader)(unsafe.Pointer(&msg)).Len
3020  	cmsg := __cmsg{__msg_length: uint32(len), __msg: uintptr(strptr)}
3021  	cmd := uint32(0)
3022  	runtime.EnterSyscall()
3023  	rc, err2, err1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____CONSOLE_A<<4, uintptr(unsafe.Pointer(&cmsg)), 0, uintptr(unsafe.Pointer(&cmd)))
3024  	runtime.ExitSyscall()
3025  	if rc != 0 {
3026  		return 0, fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
3027  	}
3028  	return 0, nil
3029  }
3030  func ZosStringToEbcdicBytes(str string, nullterm bool) (ebcdicBytes []byte) {
3031  	if nullterm {
3032  		ebcdicBytes = []byte(str + "\x00")
3033  	} else {
3034  		ebcdicBytes = []byte(str)
3035  	}
3036  	A2e(ebcdicBytes)
3037  	return
3038  }
3039  func ZosEbcdicBytesToString(b []byte, trimRight bool) (str string) {
3040  	res := make([]byte, len(b))
3041  	copy(res, b)
3042  	E2a(res)
3043  	if trimRight {
3044  		str = string(bytes.TrimRight(res, " \x00"))
3045  	} else {
3046  		str = string(res)
3047  	}
3048  	return
3049  }
3050  
3051  func fdToPath(dirfd int) (path string, err error) {
3052  	var buffer [1024]byte
3053  	// w_ctrl()
3054  	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
3055  		[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
3056  	if ret == 0 {
3057  		zb := bytes.IndexByte(buffer[:], 0)
3058  		if zb == -1 {
3059  			zb = len(buffer)
3060  		}
3061  		// __e2a_l()
3062  		runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
3063  			[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
3064  		return string(buffer[:zb]), nil
3065  	}
3066  	// __errno()
3067  	errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
3068  		[]uintptr{}))))
3069  	// __errno2()
3070  	errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
3071  		[]uintptr{}))
3072  	// strerror_r()
3073  	ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
3074  		[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
3075  	if ret == 0 {
3076  		zb := bytes.IndexByte(buffer[:], 0)
3077  		if zb == -1 {
3078  			zb = len(buffer)
3079  		}
3080  		return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
3081  	} else {
3082  		return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
3083  	}
3084  }
3085  
3086  func impl_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3087  	var _p0 *byte
3088  	_p0, err = BytePtrFromString(path)
3089  	if err != nil {
3090  		return
3091  	}
3092  	runtime.EnterSyscall()
3093  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFOAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
3094  	runtime.ExitSyscall()
3095  	if int64(r0) == -1 {
3096  		err = errnoErr2(e1, e2)
3097  	}
3098  	return
3099  }
3100  
3101  //go:nosplit
3102  func get_MkfifoatAddr() *(func(dirfd int, path string, mode uint32) (err error))
3103  
3104  var Mkfifoat = enter_Mkfifoat
3105  
3106  func enter_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3107  	funcref := get_MkfifoatAddr()
3108  	if funcptrtest(GetZosLibVec()+SYS___MKFIFOAT_A<<4, "") == 0 {
3109  		*funcref = impl_Mkfifoat
3110  	} else {
3111  		*funcref = legacy_Mkfifoat
3112  	}
3113  	return (*funcref)(dirfd, path, mode)
3114  }
3115  
3116  func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3117  	dirname, err := ZosFdToPath(dirfd)
3118  	if err != nil {
3119  		return err
3120  	}
3121  	return Mkfifo(dirname+"/"+path, mode)
3122  }
3123  
3124  //sys	Posix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT
3125  //sys	Grantpt(fildes int) (rc int, err error) = SYS_GRANTPT
3126  //sys	Unlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT
3127  
3128  func fcntlAsIs(fd uintptr, cmd int, arg uintptr) (val int, err error) {
3129  	runtime.EnterSyscall()
3130  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), arg)
3131  	runtime.ExitSyscall()
3132  	val = int(r0)
3133  	if int64(r0) == -1 {
3134  		err = errnoErr2(e1, e2)
3135  	}
3136  	return
3137  }
3138  
3139  func Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) {
3140  	switch op.(type) {
3141  	case *Flock_t:
3142  		err = FcntlFlock(fd, cmd, op.(*Flock_t))
3143  		if err != nil {
3144  			ret = -1
3145  		}
3146  		return
3147  	case int:
3148  		return FcntlInt(fd, cmd, op.(int))
3149  	case *F_cnvrt:
3150  		return fcntlAsIs(fd, cmd, uintptr(unsafe.Pointer(op.(*F_cnvrt))))
3151  	case unsafe.Pointer:
3152  		return fcntlAsIs(fd, cmd, uintptr(op.(unsafe.Pointer)))
3153  	default:
3154  		return -1, EINVAL
3155  	}
3156  	return
3157  }
3158  
3159  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
3160  	if raceenabled {
3161  		raceReleaseMerge(unsafe.Pointer(&ioSync))
3162  	}
3163  	return sendfile(outfd, infd, offset, count)
3164  }
3165  
3166  func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
3167  	// TODO: use LE call instead if the call is implemented
3168  	originalOffset, err := Seek(infd, 0, SEEK_CUR)
3169  	if err != nil {
3170  		return -1, err
3171  	}
3172  	//start reading data from in_fd
3173  	if offset != nil {
3174  		_, err := Seek(infd, *offset, SEEK_SET)
3175  		if err != nil {
3176  			return -1, err
3177  		}
3178  	}
3179  
3180  	buf := make([]byte, count)
3181  	readBuf := make([]byte, 0)
3182  	var n int = 0
3183  	for i := 0; i < count; i += n {
3184  		n, err := Read(infd, buf)
3185  		if n == 0 {
3186  			if err != nil {
3187  				return -1, err
3188  			} else { // EOF
3189  				break
3190  			}
3191  		}
3192  		readBuf = append(readBuf, buf...)
3193  		buf = buf[0:0]
3194  	}
3195  
3196  	n2, err := Write(outfd, readBuf)
3197  	if err != nil {
3198  		return -1, err
3199  	}
3200  
3201  	//When sendfile() returns, this variable will be set to the
3202  	// offset of the byte following the last byte that was read.
3203  	if offset != nil {
3204  		*offset = *offset + int64(n)
3205  		// If offset is not NULL, then sendfile() does not modify the file
3206  		// offset of in_fd
3207  		_, err := Seek(infd, originalOffset, SEEK_SET)
3208  		if err != nil {
3209  			return -1, err
3210  		}
3211  	}
3212  	return n2, nil
3213  }
3214