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

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build zos && s390x
     6  
     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  //sys   Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
   772  //sysnb	Getgid() (gid int)
   773  //sysnb	Getpid() (pid int)
   774  //sysnb	Getpgid(pid int) (pgid int, err error) = SYS_GETPGID
   775  
   776  func Getpgrp() (pid int) {
   777  	pid, _ = Getpgid(0)
   778  	return
   779  }
   780  
   781  //sysnb	Getppid() (pid int)
   782  //sys	Getpriority(which int, who int) (prio int, err error)
   783  //sysnb	Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT
   784  
   785  //sysnb getrusage(who int, rusage *rusage_zos) (err error) = SYS_GETRUSAGE
   786  
   787  func Getrusage(who int, rusage *Rusage) (err error) {
   788  	var ruz rusage_zos
   789  	err = getrusage(who, &ruz)
   790  	//Only the first two fields of Rusage are set
   791  	rusage.Utime.Sec = ruz.Utime.Sec
   792  	rusage.Utime.Usec = int64(ruz.Utime.Usec)
   793  	rusage.Stime.Sec = ruz.Stime.Sec
   794  	rusage.Stime.Usec = int64(ruz.Stime.Usec)
   795  	return
   796  }
   797  
   798  //sys	Getegid() (egid int) = SYS_GETEGID
   799  //sys	Geteuid() (euid int) = SYS_GETEUID
   800  //sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID
   801  //sysnb	Getuid() (uid int)
   802  //sysnb	Kill(pid int, sig Signal) (err error)
   803  //sys	Lchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A
   804  //sys	Link(path string, link string) (err error) = SYS___LINK_A
   805  //sys	Linkat(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error) = SYS___LINKAT_A
   806  //sys	Listen(s int, n int) (err error)
   807  //sys	lstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A
   808  
   809  func Lstat(path string, stat *Stat_t) (err error) {
   810  	var statLE Stat_LE_t
   811  	err = lstat(path, &statLE)
   812  	copyStat(stat, &statLE)
   813  	return
   814  }
   815  
   816  // for checking symlinks begins with $VERSION/ $SYSNAME/ $SYSSYMR/ $SYSSYMA/
   817  func isSpecialPath(path []byte) (v bool) {
   818  	var special = [4][8]byte{
   819  		[8]byte{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},
   820  		[8]byte{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},
   821  		[8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},
   822  		[8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}
   823  
   824  	var i, j int
   825  	for i = 0; i < len(special); i++ {
   826  		for j = 0; j < len(special[i]); j++ {
   827  			if path[j] != special[i][j] {
   828  				break
   829  			}
   830  		}
   831  		if j == len(special[i]) {
   832  			return true
   833  		}
   834  	}
   835  	return false
   836  }
   837  
   838  func realpath(srcpath string, abspath []byte) (pathlen int, errno int) {
   839  	var source [1024]byte
   840  	copy(source[:], srcpath)
   841  	source[len(srcpath)] = 0
   842  	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___REALPATH_A<<4, //__realpath_a()
   843  		[]uintptr{uintptr(unsafe.Pointer(&source[0])),
   844  			uintptr(unsafe.Pointer(&abspath[0]))})
   845  	if ret != 0 {
   846  		index := bytes.IndexByte(abspath[:], byte(0))
   847  		if index != -1 {
   848  			return index, 0
   849  		}
   850  	} else {
   851  		errptr := (*int)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{}))) //__errno()
   852  		return 0, *errptr
   853  	}
   854  	return 0, 245 // EBADDATA   245
   855  }
   856  
   857  func Readlink(path string, buf []byte) (n int, err error) {
   858  	var _p0 *byte
   859  	_p0, err = BytePtrFromString(path)
   860  	if err != nil {
   861  		return
   862  	}
   863  	var _p1 unsafe.Pointer
   864  	if len(buf) > 0 {
   865  		_p1 = unsafe.Pointer(&buf[0])
   866  	} else {
   867  		_p1 = unsafe.Pointer(&_zero)
   868  	}
   869  	n = int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___READLINK_A<<4,
   870  		[]uintptr{uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))}))
   871  	runtime.KeepAlive(unsafe.Pointer(_p0))
   872  	if n == -1 {
   873  		value := *(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))
   874  		err = errnoErr(Errno(value))
   875  	} else {
   876  		if buf[0] == '$' {
   877  			if isSpecialPath(buf[1:9]) {
   878  				cnt, err1 := realpath(path, buf)
   879  				if err1 == 0 {
   880  					n = cnt
   881  				}
   882  			}
   883  		}
   884  	}
   885  	return
   886  }
   887  
   888  func impl_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
   889  	var _p0 *byte
   890  	_p0, err = BytePtrFromString(path)
   891  	if err != nil {
   892  		return
   893  	}
   894  	var _p1 unsafe.Pointer
   895  	if len(buf) > 0 {
   896  		_p1 = unsafe.Pointer(&buf[0])
   897  	} else {
   898  		_p1 = unsafe.Pointer(&_zero)
   899  	}
   900  	runtime.EnterSyscall()
   901  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READLINKAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
   902  	runtime.ExitSyscall()
   903  	n = int(r0)
   904  	if int64(r0) == -1 {
   905  		err = errnoErr2(e1, e2)
   906  		return n, err
   907  	} else {
   908  		if buf[0] == '$' {
   909  			if isSpecialPath(buf[1:9]) {
   910  				cnt, err1 := realpath(path, buf)
   911  				if err1 == 0 {
   912  					n = cnt
   913  				}
   914  			}
   915  		}
   916  	}
   917  	return
   918  }
   919  
   920  //go:nosplit
   921  func get_ReadlinkatAddr() *(func(dirfd int, path string, buf []byte) (n int, err error))
   922  
   923  var Readlinkat = enter_Readlinkat
   924  
   925  func enter_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
   926  	funcref := get_ReadlinkatAddr()
   927  	if funcptrtest(GetZosLibVec()+SYS___READLINKAT_A<<4, "") == 0 {
   928  		*funcref = impl_Readlinkat
   929  	} else {
   930  		*funcref = error_Readlinkat
   931  	}
   932  	return (*funcref)(dirfd, path, buf)
   933  }
   934  
   935  func error_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
   936  	n = -1
   937  	err = ENOSYS
   938  	return
   939  }
   940  
   941  //sys	Mkdir(path string, mode uint32) (err error) = SYS___MKDIR_A
   942  //sys	Mkdirat(dirfd int, path string, mode uint32) (err error) = SYS___MKDIRAT_A
   943  //sys   Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A
   944  //sys	Mknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A
   945  //sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error) = SYS___MKNODAT_A
   946  //sys	PivotRoot(newroot string, oldroot string) (err error) = SYS___PIVOT_ROOT_A
   947  //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
   948  //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
   949  //sys	Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) = SYS___PRCTL_A
   950  //sysnb	Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT
   951  //sys	Rename(from string, to string) (err error) = SYS___RENAME_A
   952  //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) = SYS___RENAMEAT_A
   953  //sys	Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) = SYS___RENAMEAT2_A
   954  //sys	Rmdir(path string) (err error) = SYS___RMDIR_A
   955  //sys   Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
   956  //sys	Setegid(egid int) (err error) = SYS_SETEGID
   957  //sys	Seteuid(euid int) (err error) = SYS_SETEUID
   958  //sys	Sethostname(p []byte) (err error) = SYS___SETHOSTNAME_A
   959  //sys   Setns(fd int, nstype int) (err error) = SYS_SETNS
   960  //sys	Setpriority(which int, who int, prio int) (err error)
   961  //sysnb	Setpgid(pid int, pgid int) (err error) = SYS_SETPGID
   962  //sysnb	Setrlimit(resource int, lim *Rlimit) (err error)
   963  //sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID
   964  //sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID
   965  //sysnb	Setsid() (pid int, err error) = SYS_SETSID
   966  //sys	Setuid(uid int) (err error) = SYS_SETUID
   967  //sys	Setgid(uid int) (err error) = SYS_SETGID
   968  //sys	Shutdown(fd int, how int) (err error)
   969  //sys	stat(path string, statLE *Stat_LE_t) (err error) = SYS___STAT_A
   970  
   971  func Stat(path string, sta *Stat_t) (err error) {
   972  	var statLE Stat_LE_t
   973  	err = stat(path, &statLE)
   974  	copyStat(sta, &statLE)
   975  	return
   976  }
   977  
   978  //sys	Symlink(path string, link string) (err error) = SYS___SYMLINK_A
   979  //sys	Symlinkat(oldPath string, dirfd int, newPath string) (err error) = SYS___SYMLINKAT_A
   980  //sys	Sync() = SYS_SYNC
   981  //sys	Truncate(path string, length int64) (err error) = SYS___TRUNCATE_A
   982  //sys	Tcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR
   983  //sys	Tcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR
   984  //sys	Umask(mask int) (oldmask int)
   985  //sys	Unlink(path string) (err error) = SYS___UNLINK_A
   986  //sys	Unlinkat(dirfd int, path string, flags int) (err error) = SYS___UNLINKAT_A
   987  //sys	Utime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A
   988  
   989  //sys	open(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A
   990  
   991  func Open(path string, mode int, perm uint32) (fd int, err error) {
   992  	if mode&O_ACCMODE == 0 {
   993  		mode |= O_RDONLY
   994  	}
   995  	return open(path, mode, perm)
   996  }
   997  
   998  //sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) = SYS___OPENAT_A
   999  
  1000  func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
  1001  	if flags&O_ACCMODE == 0 {
  1002  		flags |= O_RDONLY
  1003  	}
  1004  	return openat(dirfd, path, flags, mode)
  1005  }
  1006  
  1007  //sys	openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) = SYS___OPENAT2_A
  1008  
  1009  func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
  1010  	if how.Flags&O_ACCMODE == 0 {
  1011  		how.Flags |= O_RDONLY
  1012  	}
  1013  	return openat2(dirfd, path, how, SizeofOpenHow)
  1014  }
  1015  
  1016  func ZosFdToPath(dirfd int) (path string, err error) {
  1017  	var buffer [1024]byte
  1018  	runtime.EnterSyscall()
  1019  	ret, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_W_IOCTL<<4, uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0])))
  1020  	runtime.ExitSyscall()
  1021  	if ret == 0 {
  1022  		zb := bytes.IndexByte(buffer[:], 0)
  1023  		if zb == -1 {
  1024  			zb = len(buffer)
  1025  		}
  1026  		CallLeFuncWithErr(GetZosLibVec()+SYS___E2A_L<<4, uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb))
  1027  		return string(buffer[:zb]), nil
  1028  	}
  1029  	return "", errnoErr2(e1, e2)
  1030  }
  1031  
  1032  //sys	remove(path string) (err error)
  1033  
  1034  func Remove(path string) error {
  1035  	return remove(path)
  1036  }
  1037  
  1038  const ImplementsGetwd = true
  1039  
  1040  func Getcwd(buf []byte) (n int, err error) {
  1041  	var p unsafe.Pointer
  1042  	if len(buf) > 0 {
  1043  		p = unsafe.Pointer(&buf[0])
  1044  	} else {
  1045  		p = unsafe.Pointer(&_zero)
  1046  	}
  1047  	runtime.EnterSyscall()
  1048  	r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___GETCWD_A<<4, uintptr(p), uintptr(len(buf)))
  1049  	runtime.ExitSyscall()
  1050  	n = clen(buf) + 1
  1051  	if r0 == 0 {
  1052  		err = errnoErr2(e1, e2)
  1053  	}
  1054  	return
  1055  }
  1056  
  1057  func Getwd() (wd string, err error) {
  1058  	var buf [PathMax]byte
  1059  	n, err := Getcwd(buf[0:])
  1060  	if err != nil {
  1061  		return "", err
  1062  	}
  1063  	// Getcwd returns the number of bytes written to buf, including the NUL.
  1064  	if n < 1 || n > len(buf) || buf[n-1] != 0 {
  1065  		return "", EINVAL
  1066  	}
  1067  	return string(buf[0 : n-1]), nil
  1068  }
  1069  
  1070  func Getgroups() (gids []int, err error) {
  1071  	n, err := getgroups(0, nil)
  1072  	if err != nil {
  1073  		return nil, err
  1074  	}
  1075  	if n == 0 {
  1076  		return nil, nil
  1077  	}
  1078  
  1079  	// Sanity check group count.  Max is 1<<16 on Linux.
  1080  	if n < 0 || n > 1<<20 {
  1081  		return nil, EINVAL
  1082  	}
  1083  
  1084  	a := make([]_Gid_t, n)
  1085  	n, err = getgroups(n, &a[0])
  1086  	if err != nil {
  1087  		return nil, err
  1088  	}
  1089  	gids = make([]int, n)
  1090  	for i, v := range a[0:n] {
  1091  		gids[i] = int(v)
  1092  	}
  1093  	return
  1094  }
  1095  
  1096  func Setgroups(gids []int) (err error) {
  1097  	if len(gids) == 0 {
  1098  		return setgroups(0, nil)
  1099  	}
  1100  
  1101  	a := make([]_Gid_t, len(gids))
  1102  	for i, v := range gids {
  1103  		a[i] = _Gid_t(v)
  1104  	}
  1105  	return setgroups(len(a), &a[0])
  1106  }
  1107  
  1108  func gettid() uint64
  1109  
  1110  func Gettid() (tid int) {
  1111  	return int(gettid())
  1112  }
  1113  
  1114  type WaitStatus uint32
  1115  
  1116  // Wait status is 7 bits at bottom, either 0 (exited),
  1117  // 0x7F (stopped), or a signal number that caused an exit.
  1118  // The 0x80 bit is whether there was a core dump.
  1119  // An extra number (exit code, signal causing a stop)
  1120  // is in the high bits.  At least that's the idea.
  1121  // There are various irregularities.  For example, the
  1122  // "continued" status is 0xFFFF, distinguishing itself
  1123  // from stopped via the core dump bit.
  1124  
  1125  const (
  1126  	mask    = 0x7F
  1127  	core    = 0x80
  1128  	exited  = 0x00
  1129  	stopped = 0x7F
  1130  	shift   = 8
  1131  )
  1132  
  1133  func (w WaitStatus) Exited() bool { return w&mask == exited }
  1134  
  1135  func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
  1136  
  1137  func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
  1138  
  1139  func (w WaitStatus) Continued() bool { return w == 0xFFFF }
  1140  
  1141  func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
  1142  
  1143  func (w WaitStatus) ExitStatus() int {
  1144  	if !w.Exited() {
  1145  		return -1
  1146  	}
  1147  	return int(w>>shift) & 0xFF
  1148  }
  1149  
  1150  func (w WaitStatus) Signal() Signal {
  1151  	if !w.Signaled() {
  1152  		return -1
  1153  	}
  1154  	return Signal(w & mask)
  1155  }
  1156  
  1157  func (w WaitStatus) StopSignal() Signal {
  1158  	if !w.Stopped() {
  1159  		return -1
  1160  	}
  1161  	return Signal(w>>shift) & 0xFF
  1162  }
  1163  
  1164  func (w WaitStatus) TrapCause() int { return -1 }
  1165  
  1166  //sys	waitid(idType int, id int, info *Siginfo, options int) (err error)
  1167  
  1168  func Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) {
  1169  	return waitid(idType, id, info, options)
  1170  }
  1171  
  1172  //sys	waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)
  1173  
  1174  func impl_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  1175  	runtime.EnterSyscall()
  1176  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAIT4<<4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)))
  1177  	runtime.ExitSyscall()
  1178  	wpid = int(r0)
  1179  	if int64(r0) == -1 {
  1180  		err = errnoErr2(e1, e2)
  1181  	}
  1182  	return
  1183  }
  1184  
  1185  //go:nosplit
  1186  func get_Wait4Addr() *(func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error))
  1187  
  1188  var Wait4 = enter_Wait4
  1189  
  1190  func enter_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  1191  	funcref := get_Wait4Addr()
  1192  	if funcptrtest(GetZosLibVec()+SYS_WAIT4<<4, "") == 0 {
  1193  		*funcref = impl_Wait4
  1194  	} else {
  1195  		*funcref = legacyWait4
  1196  	}
  1197  	return (*funcref)(pid, wstatus, options, rusage)
  1198  }
  1199  
  1200  func legacyWait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  1201  	// TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.
  1202  	// At the moment rusage will not be touched.
  1203  	var status _C_int
  1204  	wpid, err = waitpid(pid, &status, options)
  1205  	if wstatus != nil {
  1206  		*wstatus = WaitStatus(status)
  1207  	}
  1208  	return
  1209  }
  1210  
  1211  //sysnb	gettimeofday(tv *timeval_zos) (err error)
  1212  
  1213  func Gettimeofday(tv *Timeval) (err error) {
  1214  	var tvz timeval_zos
  1215  	err = gettimeofday(&tvz)
  1216  	tv.Sec = tvz.Sec
  1217  	tv.Usec = int64(tvz.Usec)
  1218  	return
  1219  }
  1220  
  1221  func Time(t *Time_t) (tt Time_t, err error) {
  1222  	var tv Timeval
  1223  	err = Gettimeofday(&tv)
  1224  	if err != nil {
  1225  		return 0, err
  1226  	}
  1227  	if t != nil {
  1228  		*t = Time_t(tv.Sec)
  1229  	}
  1230  	return Time_t(tv.Sec), nil
  1231  }
  1232  
  1233  func setTimespec(sec, nsec int64) Timespec {
  1234  	return Timespec{Sec: sec, Nsec: nsec}
  1235  }
  1236  
  1237  func setTimeval(sec, usec int64) Timeval { //fix
  1238  	return Timeval{Sec: sec, Usec: usec}
  1239  }
  1240  
  1241  //sysnb pipe(p *[2]_C_int) (err error)
  1242  
  1243  func Pipe(p []int) (err error) {
  1244  	if len(p) != 2 {
  1245  		return EINVAL
  1246  	}
  1247  	var pp [2]_C_int
  1248  	err = pipe(&pp)
  1249  	p[0] = int(pp[0])
  1250  	p[1] = int(pp[1])
  1251  	return
  1252  }
  1253  
  1254  //sys	utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
  1255  
  1256  func Utimes(path string, tv []Timeval) (err error) {
  1257  	if tv == nil {
  1258  		return utimes(path, nil)
  1259  	}
  1260  	if len(tv) != 2 {
  1261  		return EINVAL
  1262  	}
  1263  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  1264  }
  1265  
  1266  //sys	utimensat(dirfd int, path string, ts *[2]Timespec, flags int) (err error) = SYS___UTIMENSAT_A
  1267  
  1268  func validUtimensat() bool {
  1269  	if funcptrtest(GetZosLibVec()+SYS___UTIMENSAT_A<<4, "") == 0 {
  1270  		if name, err := getLeFuncName(GetZosLibVec() + SYS___UTIMENSAT_A<<4); err == nil {
  1271  			return name == "__utimensat_a"
  1272  		}
  1273  	}
  1274  	return false
  1275  }
  1276  
  1277  // Begin UtimesNano
  1278  
  1279  //go:nosplit
  1280  func get_UtimesNanoAddr() *(func(path string, ts []Timespec) (err error))
  1281  
  1282  var UtimesNano = enter_UtimesNano
  1283  
  1284  func enter_UtimesNano(path string, ts []Timespec) (err error) {
  1285  	funcref := get_UtimesNanoAddr()
  1286  	if validUtimensat() {
  1287  		*funcref = utimesNanoImpl
  1288  	} else {
  1289  		*funcref = legacyUtimesNano
  1290  	}
  1291  	return (*funcref)(path, ts)
  1292  }
  1293  
  1294  func utimesNanoImpl(path string, ts []Timespec) (err error) {
  1295  	if ts == nil {
  1296  		return utimensat(AT_FDCWD, path, nil, 0)
  1297  	}
  1298  	if len(ts) != 2 {
  1299  		return EINVAL
  1300  	}
  1301  	return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
  1302  }
  1303  
  1304  func legacyUtimesNano(path string, ts []Timespec) (err error) {
  1305  	if len(ts) != 2 {
  1306  		return EINVAL
  1307  	}
  1308  	// Not as efficient as it could be because Timespec and
  1309  	// Timeval have different types in the different OSes
  1310  	tv := [2]Timeval{
  1311  		NsecToTimeval(TimespecToNsec(ts[0])),
  1312  		NsecToTimeval(TimespecToNsec(ts[1])),
  1313  	}
  1314  	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  1315  }
  1316  
  1317  // End UtimesNano
  1318  
  1319  // Begin UtimesNanoAt
  1320  
  1321  //go:nosplit
  1322  func get_UtimesNanoAtAddr() *(func(dirfd int, path string, ts []Timespec, flags int) (err error))
  1323  
  1324  var UtimesNanoAt = enter_UtimesNanoAt
  1325  
  1326  func enter_UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
  1327  	funcref := get_UtimesNanoAtAddr()
  1328  	if validUtimensat() {
  1329  		*funcref = utimesNanoAtImpl
  1330  	} else {
  1331  		*funcref = legacyUtimesNanoAt
  1332  	}
  1333  	return (*funcref)(dirfd, path, ts, flags)
  1334  }
  1335  
  1336  func utimesNanoAtImpl(dirfd int, path string, ts []Timespec, flags int) (err error) {
  1337  	if ts == nil {
  1338  		return utimensat(dirfd, path, nil, flags)
  1339  	}
  1340  	if len(ts) != 2 {
  1341  		return EINVAL
  1342  	}
  1343  	return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
  1344  }
  1345  
  1346  func legacyUtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
  1347  	if path[0] != '/' {
  1348  		dirPath, err := ZosFdToPath(dirfd)
  1349  		if err != nil {
  1350  			return err
  1351  		}
  1352  		path = dirPath + "/" + path
  1353  	}
  1354  	if flags == AT_SYMLINK_NOFOLLOW {
  1355  		if len(ts) != 2 {
  1356  			return EINVAL
  1357  		}
  1358  
  1359  		if ts[0].Nsec >= 5e8 {
  1360  			ts[0].Sec++
  1361  		}
  1362  		ts[0].Nsec = 0
  1363  		if ts[1].Nsec >= 5e8 {
  1364  			ts[1].Sec++
  1365  		}
  1366  		ts[1].Nsec = 0
  1367  
  1368  		// Not as efficient as it could be because Timespec and
  1369  		// Timeval have different types in the different OSes
  1370  		tv := []Timeval{
  1371  			NsecToTimeval(TimespecToNsec(ts[0])),
  1372  			NsecToTimeval(TimespecToNsec(ts[1])),
  1373  		}
  1374  		return Lutimes(path, tv)
  1375  	}
  1376  	return UtimesNano(path, ts)
  1377  }
  1378  
  1379  // End UtimesNanoAt
  1380  
  1381  func Getsockname(fd int) (sa Sockaddr, err error) {
  1382  	var rsa RawSockaddrAny
  1383  	var len _Socklen = SizeofSockaddrAny
  1384  	if err = getsockname(fd, &rsa, &len); err != nil {
  1385  		return
  1386  	}
  1387  	// TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )
  1388  	return anyToSockaddr(0, &rsa)
  1389  }
  1390  
  1391  const (
  1392  	// identifier constants
  1393  	nwmHeaderIdentifier    = 0xd5e6d4c8
  1394  	nwmFilterIdentifier    = 0xd5e6d4c6
  1395  	nwmTCPConnIdentifier   = 0xd5e6d4c3
  1396  	nwmRecHeaderIdentifier = 0xd5e6d4d9
  1397  	nwmIPStatsIdentifier   = 0xd5e6d4c9d7e2e340
  1398  	nwmIPGStatsIdentifier  = 0xd5e6d4c9d7c7e2e3
  1399  	nwmTCPStatsIdentifier  = 0xd5e6d4e3c3d7e2e3
  1400  	nwmUDPStatsIdentifier  = 0xd5e6d4e4c4d7e2e3
  1401  	nwmICMPGStatsEntry     = 0xd5e6d4c9c3d4d7c7
  1402  	nwmICMPTStatsEntry     = 0xd5e6d4c9c3d4d7e3
  1403  
  1404  	// nwmHeader constants
  1405  	nwmVersion1   = 1
  1406  	nwmVersion2   = 2
  1407  	nwmCurrentVer = 2
  1408  
  1409  	nwmTCPConnType     = 1
  1410  	nwmGlobalStatsType = 14
  1411  
  1412  	// nwmFilter constants
  1413  	nwmFilterLclAddrMask = 0x20000000 // Local address
  1414  	nwmFilterSrcAddrMask = 0x20000000 // Source address
  1415  	nwmFilterLclPortMask = 0x10000000 // Local port
  1416  	nwmFilterSrcPortMask = 0x10000000 // Source port
  1417  
  1418  	// nwmConnEntry constants
  1419  	nwmTCPStateClosed   = 1
  1420  	nwmTCPStateListen   = 2
  1421  	nwmTCPStateSynSent  = 3
  1422  	nwmTCPStateSynRcvd  = 4
  1423  	nwmTCPStateEstab    = 5
  1424  	nwmTCPStateFinWait1 = 6
  1425  	nwmTCPStateFinWait2 = 7
  1426  	nwmTCPStateClosWait = 8
  1427  	nwmTCPStateLastAck  = 9
  1428  	nwmTCPStateClosing  = 10
  1429  	nwmTCPStateTimeWait = 11
  1430  	nwmTCPStateDeletTCB = 12
  1431  
  1432  	// Existing constants on linux
  1433  	BPF_TCP_CLOSE        = 1
  1434  	BPF_TCP_LISTEN       = 2
  1435  	BPF_TCP_SYN_SENT     = 3
  1436  	BPF_TCP_SYN_RECV     = 4
  1437  	BPF_TCP_ESTABLISHED  = 5
  1438  	BPF_TCP_FIN_WAIT1    = 6
  1439  	BPF_TCP_FIN_WAIT2    = 7
  1440  	BPF_TCP_CLOSE_WAIT   = 8
  1441  	BPF_TCP_LAST_ACK     = 9
  1442  	BPF_TCP_CLOSING      = 10
  1443  	BPF_TCP_TIME_WAIT    = 11
  1444  	BPF_TCP_NEW_SYN_RECV = -1
  1445  	BPF_TCP_MAX_STATES   = -2
  1446  )
  1447  
  1448  type nwmTriplet struct {
  1449  	offset uint32
  1450  	length uint32
  1451  	number uint32
  1452  }
  1453  
  1454  type nwmQuadruplet struct {
  1455  	offset uint32
  1456  	length uint32
  1457  	number uint32
  1458  	match  uint32
  1459  }
  1460  
  1461  type nwmHeader struct {
  1462  	ident       uint32
  1463  	length      uint32
  1464  	version     uint16
  1465  	nwmType     uint16
  1466  	bytesNeeded uint32
  1467  	options     uint32
  1468  	_           [16]byte
  1469  	inputDesc   nwmTriplet
  1470  	outputDesc  nwmQuadruplet
  1471  }
  1472  
  1473  type nwmFilter struct {
  1474  	ident         uint32
  1475  	flags         uint32
  1476  	resourceName  [8]byte
  1477  	resourceId    uint32
  1478  	listenerId    uint32
  1479  	local         [28]byte // union of sockaddr4 and sockaddr6
  1480  	remote        [28]byte // union of sockaddr4 and sockaddr6
  1481  	_             uint16
  1482  	_             uint16
  1483  	asid          uint16
  1484  	_             [2]byte
  1485  	tnLuName      [8]byte
  1486  	tnMonGrp      uint32
  1487  	tnAppl        [8]byte
  1488  	applData      [40]byte
  1489  	nInterface    [16]byte
  1490  	dVipa         [16]byte
  1491  	dVipaPfx      uint16
  1492  	dVipaPort     uint16
  1493  	dVipaFamily   byte
  1494  	_             [3]byte
  1495  	destXCF       [16]byte
  1496  	destXCFPfx    uint16
  1497  	destXCFFamily byte
  1498  	_             [1]byte
  1499  	targIP        [16]byte
  1500  	targIPPfx     uint16
  1501  	targIPFamily  byte
  1502  	_             [1]byte
  1503  	_             [20]byte
  1504  }
  1505  
  1506  type nwmRecHeader struct {
  1507  	ident  uint32
  1508  	length uint32
  1509  	number byte
  1510  	_      [3]byte
  1511  }
  1512  
  1513  type nwmTCPStatsEntry struct {
  1514  	ident             uint64
  1515  	currEstab         uint32
  1516  	activeOpened      uint32
  1517  	passiveOpened     uint32
  1518  	connClosed        uint32
  1519  	estabResets       uint32
  1520  	attemptFails      uint32
  1521  	passiveDrops      uint32
  1522  	timeWaitReused    uint32
  1523  	inSegs            uint64
  1524  	predictAck        uint32
  1525  	predictData       uint32
  1526  	inDupAck          uint32
  1527  	inBadSum          uint32
  1528  	inBadLen          uint32
  1529  	inShort           uint32
  1530  	inDiscOldTime     uint32
  1531  	inAllBeforeWin    uint32
  1532  	inSomeBeforeWin   uint32
  1533  	inAllAfterWin     uint32
  1534  	inSomeAfterWin    uint32
  1535  	inOutOfOrder      uint32
  1536  	inAfterClose      uint32
  1537  	inWinProbes       uint32
  1538  	inWinUpdates      uint32
  1539  	outWinUpdates     uint32
  1540  	outSegs           uint64
  1541  	outDelayAcks      uint32
  1542  	outRsts           uint32
  1543  	retransSegs       uint32
  1544  	retransTimeouts   uint32
  1545  	retransDrops      uint32
  1546  	pmtuRetrans       uint32
  1547  	pmtuErrors        uint32
  1548  	outWinProbes      uint32
  1549  	probeDrops        uint32
  1550  	keepAliveProbes   uint32
  1551  	keepAliveDrops    uint32
  1552  	finwait2Drops     uint32
  1553  	acceptCount       uint64
  1554  	inBulkQSegs       uint64
  1555  	inDiscards        uint64
  1556  	connFloods        uint32
  1557  	connStalls        uint32
  1558  	cfgEphemDef       uint16
  1559  	ephemInUse        uint16
  1560  	ephemHiWater      uint16
  1561  	flags             byte
  1562  	_                 [1]byte
  1563  	ephemExhaust      uint32
  1564  	smcRCurrEstabLnks uint32
  1565  	smcRLnkActTimeOut uint32
  1566  	smcRActLnkOpened  uint32
  1567  	smcRPasLnkOpened  uint32
  1568  	smcRLnksClosed    uint32
  1569  	smcRCurrEstab     uint32
  1570  	smcRActiveOpened  uint32
  1571  	smcRPassiveOpened uint32
  1572  	smcRConnClosed    uint32
  1573  	smcRInSegs        uint64
  1574  	smcROutSegs       uint64
  1575  	smcRInRsts        uint32
  1576  	smcROutRsts       uint32
  1577  	smcDCurrEstabLnks uint32
  1578  	smcDActLnkOpened  uint32
  1579  	smcDPasLnkOpened  uint32
  1580  	smcDLnksClosed    uint32
  1581  	smcDCurrEstab     uint32
  1582  	smcDActiveOpened  uint32
  1583  	smcDPassiveOpened uint32
  1584  	smcDConnClosed    uint32
  1585  	smcDInSegs        uint64
  1586  	smcDOutSegs       uint64
  1587  	smcDInRsts        uint32
  1588  	smcDOutRsts       uint32
  1589  }
  1590  
  1591  type nwmConnEntry struct {
  1592  	ident             uint32
  1593  	local             [28]byte // union of sockaddr4 and sockaddr6
  1594  	remote            [28]byte // union of sockaddr4 and sockaddr6
  1595  	startTime         [8]byte  // uint64, changed to prevent padding from being inserted
  1596  	lastActivity      [8]byte  // uint64
  1597  	bytesIn           [8]byte  // uint64
  1598  	bytesOut          [8]byte  // uint64
  1599  	inSegs            [8]byte  // uint64
  1600  	outSegs           [8]byte  // uint64
  1601  	state             uint16
  1602  	activeOpen        byte
  1603  	flag01            byte
  1604  	outBuffered       uint32
  1605  	inBuffered        uint32
  1606  	maxSndWnd         uint32
  1607  	reXmtCount        uint32
  1608  	congestionWnd     uint32
  1609  	ssThresh          uint32
  1610  	roundTripTime     uint32
  1611  	roundTripVar      uint32
  1612  	sendMSS           uint32
  1613  	sndWnd            uint32
  1614  	rcvBufSize        uint32
  1615  	sndBufSize        uint32
  1616  	outOfOrderCount   uint32
  1617  	lcl0WindowCount   uint32
  1618  	rmt0WindowCount   uint32
  1619  	dupacks           uint32
  1620  	flag02            byte
  1621  	sockOpt6Cont      byte
  1622  	asid              uint16
  1623  	resourceName      [8]byte
  1624  	resourceId        uint32
  1625  	subtask           uint32
  1626  	sockOpt           byte
  1627  	sockOpt6          byte
  1628  	clusterConnFlag   byte
  1629  	proto             byte
  1630  	targetAppl        [8]byte
  1631  	luName            [8]byte
  1632  	clientUserId      [8]byte
  1633  	logMode           [8]byte
  1634  	timeStamp         uint32
  1635  	timeStampAge      uint32
  1636  	serverResourceId  uint32
  1637  	intfName          [16]byte
  1638  	ttlsStatPol       byte
  1639  	ttlsStatConn      byte
  1640  	ttlsSSLProt       uint16
  1641  	ttlsNegCiph       [2]byte
  1642  	ttlsSecType       byte
  1643  	ttlsFIPS140Mode   byte
  1644  	ttlsUserID        [8]byte
  1645  	applData          [40]byte
  1646  	inOldestTime      [8]byte // uint64
  1647  	outOldestTime     [8]byte // uint64
  1648  	tcpTrustedPartner byte
  1649  	_                 [3]byte
  1650  	bulkDataIntfName  [16]byte
  1651  	ttlsNegCiph4      [4]byte
  1652  	smcReason         uint32
  1653  	lclSMCLinkId      uint32
  1654  	rmtSMCLinkId      uint32
  1655  	smcStatus         byte
  1656  	smcFlags          byte
  1657  	_                 [2]byte
  1658  	rcvWnd            uint32
  1659  	lclSMCBufSz       uint32
  1660  	rmtSMCBufSz       uint32
  1661  	ttlsSessID        [32]byte
  1662  	ttlsSessIDLen     int16
  1663  	_                 [1]byte
  1664  	smcDStatus        byte
  1665  	smcDReason        uint32
  1666  }
  1667  
  1668  var svcNameTable [][]byte = [][]byte{
  1669  	[]byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"), // svc_EZBNMIF4
  1670  }
  1671  
  1672  const (
  1673  	svc_EZBNMIF4 = 0
  1674  )
  1675  
  1676  func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
  1677  	jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40") // "*"
  1678  	responseBuffer := [4096]byte{0}
  1679  	var bufferAlet, reasonCode uint32 = 0, 0
  1680  	var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
  1681  
  1682  	dsa := [18]uint64{0}
  1683  	var argv [7]unsafe.Pointer
  1684  	argv[0] = unsafe.Pointer(&jobname[0])
  1685  	argv[1] = unsafe.Pointer(&responseBuffer[0])
  1686  	argv[2] = unsafe.Pointer(&bufferAlet)
  1687  	argv[3] = unsafe.Pointer(&bufferLen)
  1688  	argv[4] = unsafe.Pointer(&returnValue)
  1689  	argv[5] = unsafe.Pointer(&returnCode)
  1690  	argv[6] = unsafe.Pointer(&reasonCode)
  1691  
  1692  	request := (*struct {
  1693  		header nwmHeader
  1694  		filter nwmFilter
  1695  	})(unsafe.Pointer(&responseBuffer[0]))
  1696  
  1697  	EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
  1698  	if EZBNMIF4 == nil {
  1699  		return nil, errnoErr(EINVAL)
  1700  	}
  1701  
  1702  	// GetGlobalStats EZBNMIF4 call
  1703  	request.header.ident = nwmHeaderIdentifier
  1704  	request.header.length = uint32(unsafe.Sizeof(request.header))
  1705  	request.header.version = nwmCurrentVer
  1706  	request.header.nwmType = nwmGlobalStatsType
  1707  	request.header.options = 0x80000000
  1708  
  1709  	svcCall(EZBNMIF4, &argv[0], &dsa[0])
  1710  
  1711  	// outputDesc field is filled by EZBNMIF4 on success
  1712  	if returnCode != 0 || request.header.outputDesc.offset == 0 {
  1713  		return nil, errnoErr(EINVAL)
  1714  	}
  1715  
  1716  	// Check that EZBNMIF4 returned a nwmRecHeader
  1717  	recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
  1718  	if recHeader.ident != nwmRecHeaderIdentifier {
  1719  		return nil, errnoErr(EINVAL)
  1720  	}
  1721  
  1722  	// Parse nwmTriplets to get offsets of returned entries
  1723  	var sections []*uint64
  1724  	var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
  1725  	for i := uint32(0); i < uint32(recHeader.number); i++ {
  1726  		offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
  1727  		sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
  1728  		for j := uint32(0); j < sectionDesc.number; j++ {
  1729  			offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
  1730  			sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
  1731  		}
  1732  	}
  1733  
  1734  	// Find nwmTCPStatsEntry in returned entries
  1735  	var tcpStats *nwmTCPStatsEntry = nil
  1736  	for _, ptr := range sections {
  1737  		switch *ptr {
  1738  		case nwmTCPStatsIdentifier:
  1739  			if tcpStats != nil {
  1740  				return nil, errnoErr(EINVAL)
  1741  			}
  1742  			tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
  1743  		case nwmIPStatsIdentifier:
  1744  		case nwmIPGStatsIdentifier:
  1745  		case nwmUDPStatsIdentifier:
  1746  		case nwmICMPGStatsEntry:
  1747  		case nwmICMPTStatsEntry:
  1748  		default:
  1749  			return nil, errnoErr(EINVAL)
  1750  		}
  1751  	}
  1752  	if tcpStats == nil {
  1753  		return nil, errnoErr(EINVAL)
  1754  	}
  1755  
  1756  	// GetConnectionDetail EZBNMIF4 call
  1757  	responseBuffer = [4096]byte{0}
  1758  	dsa = [18]uint64{0}
  1759  	bufferAlet, reasonCode = 0, 0
  1760  	bufferLen, returnValue, returnCode = 4096, 0, 0
  1761  	nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process
  1762  	nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
  1763  	argv[0] = unsafe.Pointer(uintptr(*nameptr))
  1764  
  1765  	request.header.ident = nwmHeaderIdentifier
  1766  	request.header.length = uint32(unsafe.Sizeof(request.header))
  1767  	request.header.version = nwmCurrentVer
  1768  	request.header.nwmType = nwmTCPConnType
  1769  	request.header.options = 0x80000000
  1770  
  1771  	request.filter.ident = nwmFilterIdentifier
  1772  
  1773  	var localSockaddr RawSockaddrAny
  1774  	socklen := _Socklen(SizeofSockaddrAny)
  1775  	err := getsockname(fd, &localSockaddr, &socklen)
  1776  	if err != nil {
  1777  		return nil, errnoErr(EINVAL)
  1778  	}
  1779  	if localSockaddr.Addr.Family == AF_INET {
  1780  		localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
  1781  		localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
  1782  		localSockFilter.Family = AF_INET
  1783  		var i int
  1784  		for i = 0; i < 4; i++ {
  1785  			if localSockaddr.Addr[i] != 0 {
  1786  				break
  1787  			}
  1788  		}
  1789  		if i != 4 {
  1790  			request.filter.flags |= nwmFilterLclAddrMask
  1791  			for i = 0; i < 4; i++ {
  1792  				localSockFilter.Addr[i] = localSockaddr.Addr[i]
  1793  			}
  1794  		}
  1795  		if localSockaddr.Port != 0 {
  1796  			request.filter.flags |= nwmFilterLclPortMask
  1797  			localSockFilter.Port = localSockaddr.Port
  1798  		}
  1799  	} else if localSockaddr.Addr.Family == AF_INET6 {
  1800  		localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
  1801  		localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
  1802  		localSockFilter.Family = AF_INET6
  1803  		var i int
  1804  		for i = 0; i < 16; i++ {
  1805  			if localSockaddr.Addr[i] != 0 {
  1806  				break
  1807  			}
  1808  		}
  1809  		if i != 16 {
  1810  			request.filter.flags |= nwmFilterLclAddrMask
  1811  			for i = 0; i < 16; i++ {
  1812  				localSockFilter.Addr[i] = localSockaddr.Addr[i]
  1813  			}
  1814  		}
  1815  		if localSockaddr.Port != 0 {
  1816  			request.filter.flags |= nwmFilterLclPortMask
  1817  			localSockFilter.Port = localSockaddr.Port
  1818  		}
  1819  	}
  1820  
  1821  	svcCall(EZBNMIF4, &argv[0], &dsa[0])
  1822  
  1823  	// outputDesc field is filled by EZBNMIF4 on success
  1824  	if returnCode != 0 || request.header.outputDesc.offset == 0 {
  1825  		return nil, errnoErr(EINVAL)
  1826  	}
  1827  
  1828  	// Check that EZBNMIF4 returned a nwmConnEntry
  1829  	conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
  1830  	if conn.ident != nwmTCPConnIdentifier {
  1831  		return nil, errnoErr(EINVAL)
  1832  	}
  1833  
  1834  	// Copy data from the returned data structures into tcpInfo
  1835  	// Stats from nwmConnEntry are specific to that connection.
  1836  	// Stats from nwmTCPStatsEntry are global (to the interface?)
  1837  	// Fields may not be an exact match. Some fields have no equivalent.
  1838  	var tcpinfo TCPInfo
  1839  	tcpinfo.State = uint8(conn.state)
  1840  	tcpinfo.Ca_state = 0 // dummy
  1841  	tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
  1842  	tcpinfo.Probes = uint8(tcpStats.outWinProbes)
  1843  	tcpinfo.Backoff = 0 // dummy
  1844  	tcpinfo.Options = 0 // dummy
  1845  	tcpinfo.Rto = tcpStats.retransTimeouts
  1846  	tcpinfo.Ato = tcpStats.outDelayAcks
  1847  	tcpinfo.Snd_mss = conn.sendMSS
  1848  	tcpinfo.Rcv_mss = conn.sendMSS // dummy
  1849  	tcpinfo.Unacked = 0            // dummy
  1850  	tcpinfo.Sacked = 0             // dummy
  1851  	tcpinfo.Lost = 0               // dummy
  1852  	tcpinfo.Retrans = conn.reXmtCount
  1853  	tcpinfo.Fackets = 0 // dummy
  1854  	tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
  1855  	tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
  1856  	tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  1857  	tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
  1858  	tcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate
  1859  	tcpinfo.Rcv_ssthresh = conn.ssThresh
  1860  	tcpinfo.Rtt = conn.roundTripTime
  1861  	tcpinfo.Rttvar = conn.roundTripVar
  1862  	tcpinfo.Snd_ssthresh = conn.ssThresh // dummy
  1863  	tcpinfo.Snd_cwnd = conn.congestionWnd
  1864  	tcpinfo.Advmss = conn.sendMSS        // dummy
  1865  	tcpinfo.Reordering = 0               // dummy
  1866  	tcpinfo.Rcv_rtt = conn.roundTripTime // dummy
  1867  	tcpinfo.Rcv_space = conn.sendMSS     // dummy
  1868  	tcpinfo.Total_retrans = conn.reXmtCount
  1869  
  1870  	svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
  1871  
  1872  	return &tcpinfo, nil
  1873  }
  1874  
  1875  // GetsockoptString returns the string value of the socket option opt for the
  1876  // socket associated with fd at the given socket level.
  1877  func GetsockoptString(fd, level, opt int) (string, error) {
  1878  	buf := make([]byte, 256)
  1879  	vallen := _Socklen(len(buf))
  1880  	err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
  1881  	if err != nil {
  1882  		return "", err
  1883  	}
  1884  
  1885  	return ByteSliceToString(buf[:vallen]), nil
  1886  }
  1887  
  1888  func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  1889  	var msg Msghdr
  1890  	var rsa RawSockaddrAny
  1891  	msg.Name = (*byte)(unsafe.Pointer(&rsa))
  1892  	msg.Namelen = SizeofSockaddrAny
  1893  	var iov Iovec
  1894  	if len(p) > 0 {
  1895  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1896  		iov.SetLen(len(p))
  1897  	}
  1898  	var dummy byte
  1899  	if len(oob) > 0 {
  1900  		// receive at least one normal byte
  1901  		if len(p) == 0 {
  1902  			iov.Base = &dummy
  1903  			iov.SetLen(1)
  1904  		}
  1905  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1906  		msg.SetControllen(len(oob))
  1907  	}
  1908  	msg.Iov = &iov
  1909  	msg.Iovlen = 1
  1910  	if n, err = recvmsg(fd, &msg, flags); err != nil {
  1911  		return
  1912  	}
  1913  	oobn = int(msg.Controllen)
  1914  	recvflags = int(msg.Flags)
  1915  	// source address is only specified if the socket is unconnected
  1916  	if rsa.Addr.Family != AF_UNSPEC {
  1917  		// TODO(neeilan): Remove 0 arg added to get this compiling on z/OS
  1918  		from, err = anyToSockaddr(0, &rsa)
  1919  	}
  1920  	return
  1921  }
  1922  
  1923  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
  1924  	_, err = SendmsgN(fd, p, oob, to, flags)
  1925  	return
  1926  }
  1927  
  1928  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
  1929  	var ptr unsafe.Pointer
  1930  	var salen _Socklen
  1931  	if to != nil {
  1932  		var err error
  1933  		ptr, salen, err = to.sockaddr()
  1934  		if err != nil {
  1935  			return 0, err
  1936  		}
  1937  	}
  1938  	var msg Msghdr
  1939  	msg.Name = (*byte)(unsafe.Pointer(ptr))
  1940  	msg.Namelen = int32(salen)
  1941  	var iov Iovec
  1942  	if len(p) > 0 {
  1943  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
  1944  		iov.SetLen(len(p))
  1945  	}
  1946  	var dummy byte
  1947  	if len(oob) > 0 {
  1948  		// send at least one normal byte
  1949  		if len(p) == 0 {
  1950  			iov.Base = &dummy
  1951  			iov.SetLen(1)
  1952  		}
  1953  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
  1954  		msg.SetControllen(len(oob))
  1955  	}
  1956  	msg.Iov = &iov
  1957  	msg.Iovlen = 1
  1958  	if n, err = sendmsg(fd, &msg, flags); err != nil {
  1959  		return 0, err
  1960  	}
  1961  	if len(oob) > 0 && len(p) == 0 {
  1962  		n = 0
  1963  	}
  1964  	return n, nil
  1965  }
  1966  
  1967  func Opendir(name string) (uintptr, error) {
  1968  	p, err := BytePtrFromString(name)
  1969  	if err != nil {
  1970  		return 0, err
  1971  	}
  1972  	err = nil
  1973  	runtime.EnterSyscall()
  1974  	dir, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___OPENDIR_A<<4, uintptr(unsafe.Pointer(p)))
  1975  	runtime.ExitSyscall()
  1976  	runtime.KeepAlive(unsafe.Pointer(p))
  1977  	if dir == 0 {
  1978  		err = errnoErr2(e1, e2)
  1979  	}
  1980  	return dir, err
  1981  }
  1982  
  1983  // clearsyscall.Errno resets the errno value to 0.
  1984  func clearErrno()
  1985  
  1986  func Closedir(dir uintptr) error {
  1987  	runtime.EnterSyscall()
  1988  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSEDIR<<4, dir)
  1989  	runtime.ExitSyscall()
  1990  	if r0 != 0 {
  1991  		return errnoErr2(e1, e2)
  1992  	}
  1993  	return nil
  1994  }
  1995  
  1996  func Seekdir(dir uintptr, pos int) {
  1997  	runtime.EnterSyscall()
  1998  	CallLeFuncWithErr(GetZosLibVec()+SYS_SEEKDIR<<4, dir, uintptr(pos))
  1999  	runtime.ExitSyscall()
  2000  }
  2001  
  2002  func Telldir(dir uintptr) (int, error) {
  2003  	p, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TELLDIR<<4, dir)
  2004  	pos := int(p)
  2005  	if int64(p) == -1 {
  2006  		return pos, errnoErr2(e1, e2)
  2007  	}
  2008  	return pos, nil
  2009  }
  2010  
  2011  // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
  2012  func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
  2013  	// struct flock is packed on z/OS. We can't emulate that in Go so
  2014  	// instead we pack it here.
  2015  	var flock [24]byte
  2016  	*(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
  2017  	*(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
  2018  	*(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
  2019  	*(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
  2020  	*(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
  2021  	runtime.EnterSyscall()
  2022  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
  2023  	runtime.ExitSyscall()
  2024  	lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
  2025  	lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
  2026  	lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
  2027  	lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
  2028  	lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
  2029  	if r0 == 0 {
  2030  		return nil
  2031  	}
  2032  	return errnoErr2(e1, e2)
  2033  }
  2034  
  2035  func impl_Flock(fd int, how int) (err error) {
  2036  	runtime.EnterSyscall()
  2037  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FLOCK<<4, uintptr(fd), uintptr(how))
  2038  	runtime.ExitSyscall()
  2039  	if int64(r0) == -1 {
  2040  		err = errnoErr2(e1, e2)
  2041  	}
  2042  	return
  2043  }
  2044  
  2045  //go:nosplit
  2046  func get_FlockAddr() *(func(fd int, how int) (err error))
  2047  
  2048  var Flock = enter_Flock
  2049  
  2050  func validFlock(fp uintptr) bool {
  2051  	if funcptrtest(GetZosLibVec()+SYS_FLOCK<<4, "") == 0 {
  2052  		if name, err := getLeFuncName(GetZosLibVec() + SYS_FLOCK<<4); err == nil {
  2053  			return name == "flock"
  2054  		}
  2055  	}
  2056  	return false
  2057  }
  2058  
  2059  func enter_Flock(fd int, how int) (err error) {
  2060  	funcref := get_FlockAddr()
  2061  	if validFlock(GetZosLibVec() + SYS_FLOCK<<4) {
  2062  		*funcref = impl_Flock
  2063  	} else {
  2064  		*funcref = legacyFlock
  2065  	}
  2066  	return (*funcref)(fd, how)
  2067  }
  2068  
  2069  func legacyFlock(fd int, how int) error {
  2070  
  2071  	var flock_type int16
  2072  	var fcntl_cmd int
  2073  
  2074  	switch how {
  2075  	case LOCK_SH | LOCK_NB:
  2076  		flock_type = F_RDLCK
  2077  		fcntl_cmd = F_SETLK
  2078  	case LOCK_EX | LOCK_NB:
  2079  		flock_type = F_WRLCK
  2080  		fcntl_cmd = F_SETLK
  2081  	case LOCK_EX:
  2082  		flock_type = F_WRLCK
  2083  		fcntl_cmd = F_SETLKW
  2084  	case LOCK_UN:
  2085  		flock_type = F_UNLCK
  2086  		fcntl_cmd = F_SETLKW
  2087  	default:
  2088  	}
  2089  
  2090  	flock := Flock_t{
  2091  		Type:   int16(flock_type),
  2092  		Whence: int16(0),
  2093  		Start:  int64(0),
  2094  		Len:    int64(0),
  2095  		Pid:    int32(Getppid()),
  2096  	}
  2097  
  2098  	err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
  2099  	return err
  2100  }
  2101  
  2102  func Mlock(b []byte) (err error) {
  2103  	runtime.EnterSyscall()
  2104  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
  2105  	runtime.ExitSyscall()
  2106  	if r0 != 0 {
  2107  		err = errnoErr2(e1, e2)
  2108  	}
  2109  	return
  2110  }
  2111  
  2112  func Mlock2(b []byte, flags int) (err error) {
  2113  	runtime.EnterSyscall()
  2114  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
  2115  	runtime.ExitSyscall()
  2116  	if r0 != 0 {
  2117  		err = errnoErr2(e1, e2)
  2118  	}
  2119  	return
  2120  }
  2121  
  2122  func Mlockall(flags int) (err error) {
  2123  	runtime.EnterSyscall()
  2124  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
  2125  	runtime.ExitSyscall()
  2126  	if r0 != 0 {
  2127  		err = errnoErr2(e1, e2)
  2128  	}
  2129  	return
  2130  }
  2131  
  2132  func Munlock(b []byte) (err error) {
  2133  	runtime.EnterSyscall()
  2134  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
  2135  	runtime.ExitSyscall()
  2136  	if r0 != 0 {
  2137  		err = errnoErr2(e1, e2)
  2138  	}
  2139  	return
  2140  }
  2141  
  2142  func Munlockall() (err error) {
  2143  	runtime.EnterSyscall()
  2144  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
  2145  	runtime.ExitSyscall()
  2146  	if r0 != 0 {
  2147  		err = errnoErr2(e1, e2)
  2148  	}
  2149  	return
  2150  }
  2151  
  2152  func ClockGettime(clockid int32, ts *Timespec) error {
  2153  
  2154  	var ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise
  2155  	var nsec_per_sec int64 = 1000000000
  2156  
  2157  	if ts == nil {
  2158  		return EFAULT
  2159  	}
  2160  	if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
  2161  		var nanotime int64 = runtime.Nanotime1()
  2162  		ts.Sec = nanotime / nsec_per_sec
  2163  		ts.Nsec = nanotime % nsec_per_sec
  2164  	} else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
  2165  		var tm Tms
  2166  		_, err := Times(&tm)
  2167  		if err != nil {
  2168  			return EFAULT
  2169  		}
  2170  		ts.Sec = int64(tm.Utime / ticks_per_sec)
  2171  		ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
  2172  	} else {
  2173  		return EINVAL
  2174  	}
  2175  	return nil
  2176  }
  2177  
  2178  // Chtag
  2179  
  2180  //go:nosplit
  2181  func get_ChtagAddr() *(func(path string, ccsid uint64, textbit uint64) error)
  2182  
  2183  var Chtag = enter_Chtag
  2184  
  2185  func enter_Chtag(path string, ccsid uint64, textbit uint64) error {
  2186  	funcref := get_ChtagAddr()
  2187  	if validSetxattr() {
  2188  		*funcref = impl_Chtag
  2189  	} else {
  2190  		*funcref = legacy_Chtag
  2191  	}
  2192  	return (*funcref)(path, ccsid, textbit)
  2193  }
  2194  
  2195  func legacy_Chtag(path string, ccsid uint64, textbit uint64) error {
  2196  	tag := ccsid<<16 | textbit<<15
  2197  	var tag_buff [8]byte
  2198  	DecodeData(tag_buff[:], 8, tag)
  2199  	return Setxattr(path, "filetag", tag_buff[:], XATTR_REPLACE)
  2200  }
  2201  
  2202  func impl_Chtag(path string, ccsid uint64, textbit uint64) error {
  2203  	tag := ccsid<<16 | textbit<<15
  2204  	var tag_buff [4]byte
  2205  	DecodeData(tag_buff[:], 4, tag)
  2206  	return Setxattr(path, "system.filetag", tag_buff[:], XATTR_REPLACE)
  2207  }
  2208  
  2209  // End of Chtag
  2210  
  2211  // Nanosleep
  2212  
  2213  //go:nosplit
  2214  func get_NanosleepAddr() *(func(time *Timespec, leftover *Timespec) error)
  2215  
  2216  var Nanosleep = enter_Nanosleep
  2217  
  2218  func enter_Nanosleep(time *Timespec, leftover *Timespec) error {
  2219  	funcref := get_NanosleepAddr()
  2220  	if funcptrtest(GetZosLibVec()+SYS_NANOSLEEP<<4, "") == 0 {
  2221  		*funcref = impl_Nanosleep
  2222  	} else {
  2223  		*funcref = legacyNanosleep
  2224  	}
  2225  	return (*funcref)(time, leftover)
  2226  }
  2227  
  2228  func impl_Nanosleep(time *Timespec, leftover *Timespec) error {
  2229  	runtime.EnterSyscall()
  2230  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_NANOSLEEP<<4, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)))
  2231  	runtime.ExitSyscall()
  2232  	if int64(r0) == -1 {
  2233  		return errnoErr2(e1, e2)
  2234  	}
  2235  	return nil
  2236  }
  2237  
  2238  func legacyNanosleep(time *Timespec, leftover *Timespec) error {
  2239  	t0 := runtime.Nanotime1()
  2240  	var secrem uint32
  2241  	var nsecrem uint32
  2242  	total := time.Sec*1000000000 + time.Nsec
  2243  	elapsed := runtime.Nanotime1() - t0
  2244  	var rv int32
  2245  	var rc int32
  2246  	var err error
  2247  	// repeatedly sleep for 1 second until less than 1 second left
  2248  	for total-elapsed > 1000000000 {
  2249  		rv, rc, _ = BpxCondTimedWait(uint32(1), uint32(0), uint32(CW_CONDVAR), &secrem, &nsecrem)
  2250  		if rv != 0 && rc != 112 { // 112 is EAGAIN
  2251  			if leftover != nil && rc == 120 { // 120 is EINTR
  2252  				leftover.Sec = int64(secrem)
  2253  				leftover.Nsec = int64(nsecrem)
  2254  			}
  2255  			err = Errno(rc)
  2256  			return err
  2257  		}
  2258  		elapsed = runtime.Nanotime1() - t0
  2259  	}
  2260  	// sleep the remainder
  2261  	if total > elapsed {
  2262  		rv, rc, _ = BpxCondTimedWait(uint32(0), uint32(total-elapsed), uint32(CW_CONDVAR), &secrem, &nsecrem)
  2263  	}
  2264  	if leftover != nil && rc == 120 {
  2265  		leftover.Sec = int64(secrem)
  2266  		leftover.Nsec = int64(nsecrem)
  2267  	}
  2268  	if rv != 0 && rc != 112 {
  2269  		err = Errno(rc)
  2270  	}
  2271  	return err
  2272  }
  2273  
  2274  // End of Nanosleep
  2275  
  2276  var (
  2277  	Stdin  = 0
  2278  	Stdout = 1
  2279  	Stderr = 2
  2280  )
  2281  
  2282  // Do the interface allocations only once for common
  2283  // Errno values.
  2284  var (
  2285  	errEAGAIN error = syscall.EAGAIN
  2286  	errEINVAL error = syscall.EINVAL
  2287  	errENOENT error = syscall.ENOENT
  2288  )
  2289  
  2290  var ZosTraceLevel int
  2291  var ZosTracefile *os.File
  2292  
  2293  var (
  2294  	signalNameMapOnce sync.Once
  2295  	signalNameMap     map[string]syscall.Signal
  2296  )
  2297  
  2298  // errnoErr returns common boxed Errno values, to prevent
  2299  // allocations at runtime.
  2300  func errnoErr(e Errno) error {
  2301  	switch e {
  2302  	case 0:
  2303  		return nil
  2304  	case EAGAIN:
  2305  		return errEAGAIN
  2306  	case EINVAL:
  2307  		return errEINVAL
  2308  	case ENOENT:
  2309  		return errENOENT
  2310  	}
  2311  	return e
  2312  }
  2313  
  2314  var reg *regexp.Regexp
  2315  
  2316  // enhanced with zos specific errno2
  2317  func errnoErr2(e Errno, e2 uintptr) error {
  2318  	switch e {
  2319  	case 0:
  2320  		return nil
  2321  	case EAGAIN:
  2322  		return errEAGAIN
  2323  		/*
  2324  			Allow the retrieval of errno2 for EINVAL and ENOENT on zos
  2325  				case EINVAL:
  2326  					return errEINVAL
  2327  				case ENOENT:
  2328  					return errENOENT
  2329  		*/
  2330  	}
  2331  	if ZosTraceLevel > 0 {
  2332  		var name string
  2333  		if reg == nil {
  2334  			reg = regexp.MustCompile("(^unix\\.[^/]+$|.*\\/unix\\.[^/]+$)")
  2335  		}
  2336  		i := 1
  2337  		pc, file, line, ok := runtime.Caller(i)
  2338  		if ok {
  2339  			name = runtime.FuncForPC(pc).Name()
  2340  		}
  2341  		for ok && reg.MatchString(runtime.FuncForPC(pc).Name()) {
  2342  			i += 1
  2343  			pc, file, line, ok = runtime.Caller(i)
  2344  		}
  2345  		if ok {
  2346  			if ZosTracefile == nil {
  2347  				ZosConsolePrintf("From %s:%d\n", file, line)
  2348  				ZosConsolePrintf("%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
  2349  			} else {
  2350  				fmt.Fprintf(ZosTracefile, "From %s:%d\n", file, line)
  2351  				fmt.Fprintf(ZosTracefile, "%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
  2352  			}
  2353  		} else {
  2354  			if ZosTracefile == nil {
  2355  				ZosConsolePrintf("%s (errno2=0x%x)\n", e.Error(), e2)
  2356  			} else {
  2357  				fmt.Fprintf(ZosTracefile, "%s (errno2=0x%x)\n", e.Error(), e2)
  2358  			}
  2359  		}
  2360  	}
  2361  	return e
  2362  }
  2363  
  2364  // ErrnoName returns the error name for error number e.
  2365  func ErrnoName(e Errno) string {
  2366  	i := sort.Search(len(errorList), func(i int) bool {
  2367  		return errorList[i].num >= e
  2368  	})
  2369  	if i < len(errorList) && errorList[i].num == e {
  2370  		return errorList[i].name
  2371  	}
  2372  	return ""
  2373  }
  2374  
  2375  // SignalName returns the signal name for signal number s.
  2376  func SignalName(s syscall.Signal) string {
  2377  	i := sort.Search(len(signalList), func(i int) bool {
  2378  		return signalList[i].num >= s
  2379  	})
  2380  	if i < len(signalList) && signalList[i].num == s {
  2381  		return signalList[i].name
  2382  	}
  2383  	return ""
  2384  }
  2385  
  2386  // SignalNum returns the syscall.Signal for signal named s,
  2387  // or 0 if a signal with such name is not found.
  2388  // The signal name should start with "SIG".
  2389  func SignalNum(s string) syscall.Signal {
  2390  	signalNameMapOnce.Do(func() {
  2391  		signalNameMap = make(map[string]syscall.Signal, len(signalList))
  2392  		for _, signal := range signalList {
  2393  			signalNameMap[signal.name] = signal.num
  2394  		}
  2395  	})
  2396  	return signalNameMap[s]
  2397  }
  2398  
  2399  // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
  2400  func clen(n []byte) int {
  2401  	i := bytes.IndexByte(n, 0)
  2402  	if i == -1 {
  2403  		i = len(n)
  2404  	}
  2405  	return i
  2406  }
  2407  
  2408  // Mmap manager, for use by operating system-specific implementations.
  2409  
  2410  type mmapper struct {
  2411  	sync.Mutex
  2412  	active map[*byte][]byte // active mappings; key is last byte in mapping
  2413  	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
  2414  	munmap func(addr uintptr, length uintptr) error
  2415  }
  2416  
  2417  func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  2418  	if length <= 0 {
  2419  		return nil, EINVAL
  2420  	}
  2421  
  2422  	// Set __MAP_64 by default
  2423  	flags |= __MAP_64
  2424  
  2425  	// Map the requested memory.
  2426  	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
  2427  	if errno != nil {
  2428  		return nil, errno
  2429  	}
  2430  
  2431  	// Slice memory layout
  2432  	var sl = struct {
  2433  		addr uintptr
  2434  		len  int
  2435  		cap  int
  2436  	}{addr, length, length}
  2437  
  2438  	// Use unsafe to turn sl into a []byte.
  2439  	b := *(*[]byte)(unsafe.Pointer(&sl))
  2440  
  2441  	// Register mapping in m and return it.
  2442  	p := &b[cap(b)-1]
  2443  	m.Lock()
  2444  	defer m.Unlock()
  2445  	m.active[p] = b
  2446  	return b, nil
  2447  }
  2448  
  2449  func (m *mmapper) Munmap(data []byte) (err error) {
  2450  	if len(data) == 0 || len(data) != cap(data) {
  2451  		return EINVAL
  2452  	}
  2453  
  2454  	// Find the base of the mapping.
  2455  	p := &data[cap(data)-1]
  2456  	m.Lock()
  2457  	defer m.Unlock()
  2458  	b := m.active[p]
  2459  	if b == nil || &b[0] != &data[0] {
  2460  		return EINVAL
  2461  	}
  2462  
  2463  	// Unmap the memory and update m.
  2464  	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
  2465  		return errno
  2466  	}
  2467  	delete(m.active, p)
  2468  	return nil
  2469  }
  2470  
  2471  func Read(fd int, p []byte) (n int, err error) {
  2472  	n, err = read(fd, p)
  2473  	if raceenabled {
  2474  		if n > 0 {
  2475  			raceWriteRange(unsafe.Pointer(&p[0]), n)
  2476  		}
  2477  		if err == nil {
  2478  			raceAcquire(unsafe.Pointer(&ioSync))
  2479  		}
  2480  	}
  2481  	return
  2482  }
  2483  
  2484  func Write(fd int, p []byte) (n int, err error) {
  2485  	if raceenabled {
  2486  		raceReleaseMerge(unsafe.Pointer(&ioSync))
  2487  	}
  2488  	n, err = write(fd, p)
  2489  	if raceenabled && n > 0 {
  2490  		raceReadRange(unsafe.Pointer(&p[0]), n)
  2491  	}
  2492  	return
  2493  }
  2494  
  2495  // For testing: clients can set this flag to force
  2496  // creation of IPv6 sockets to return EAFNOSUPPORT.
  2497  var SocketDisableIPv6 bool
  2498  
  2499  // Sockaddr represents a socket address.
  2500  type Sockaddr interface {
  2501  	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
  2502  }
  2503  
  2504  // SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
  2505  type SockaddrInet4 struct {
  2506  	Port int
  2507  	Addr [4]byte
  2508  	raw  RawSockaddrInet4
  2509  }
  2510  
  2511  // SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
  2512  type SockaddrInet6 struct {
  2513  	Port   int
  2514  	ZoneId uint32
  2515  	Addr   [16]byte
  2516  	raw    RawSockaddrInet6
  2517  }
  2518  
  2519  // SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
  2520  type SockaddrUnix struct {
  2521  	Name string
  2522  	raw  RawSockaddrUnix
  2523  }
  2524  
  2525  func Bind(fd int, sa Sockaddr) (err error) {
  2526  	ptr, n, err := sa.sockaddr()
  2527  	if err != nil {
  2528  		return err
  2529  	}
  2530  	return bind(fd, ptr, n)
  2531  }
  2532  
  2533  func Connect(fd int, sa Sockaddr) (err error) {
  2534  	ptr, n, err := sa.sockaddr()
  2535  	if err != nil {
  2536  		return err
  2537  	}
  2538  	return connect(fd, ptr, n)
  2539  }
  2540  
  2541  func Getpeername(fd int) (sa Sockaddr, err error) {
  2542  	var rsa RawSockaddrAny
  2543  	var len _Socklen = SizeofSockaddrAny
  2544  	if err = getpeername(fd, &rsa, &len); err != nil {
  2545  		return
  2546  	}
  2547  	return anyToSockaddr(fd, &rsa)
  2548  }
  2549  
  2550  func GetsockoptByte(fd, level, opt int) (value byte, err error) {
  2551  	var n byte
  2552  	vallen := _Socklen(1)
  2553  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  2554  	return n, err
  2555  }
  2556  
  2557  func GetsockoptInt(fd, level, opt int) (value int, err error) {
  2558  	var n int32
  2559  	vallen := _Socklen(4)
  2560  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  2561  	return int(n), err
  2562  }
  2563  
  2564  func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
  2565  	vallen := _Socklen(4)
  2566  	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
  2567  	return value, err
  2568  }
  2569  
  2570  func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
  2571  	var value IPMreq
  2572  	vallen := _Socklen(SizeofIPMreq)
  2573  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  2574  	return &value, err
  2575  }
  2576  
  2577  func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
  2578  	var value IPv6Mreq
  2579  	vallen := _Socklen(SizeofIPv6Mreq)
  2580  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  2581  	return &value, err
  2582  }
  2583  
  2584  func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
  2585  	var value IPv6MTUInfo
  2586  	vallen := _Socklen(SizeofIPv6MTUInfo)
  2587  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  2588  	return &value, err
  2589  }
  2590  
  2591  func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
  2592  	var value ICMPv6Filter
  2593  	vallen := _Socklen(SizeofICMPv6Filter)
  2594  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
  2595  	return &value, err
  2596  }
  2597  
  2598  func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
  2599  	var linger Linger
  2600  	vallen := _Socklen(SizeofLinger)
  2601  	err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
  2602  	return &linger, err
  2603  }
  2604  
  2605  func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
  2606  	var tv Timeval
  2607  	vallen := _Socklen(unsafe.Sizeof(tv))
  2608  	err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
  2609  	return &tv, err
  2610  }
  2611  
  2612  func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
  2613  	var n uint64
  2614  	vallen := _Socklen(8)
  2615  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
  2616  	return n, err
  2617  }
  2618  
  2619  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
  2620  	var rsa RawSockaddrAny
  2621  	var len _Socklen = SizeofSockaddrAny
  2622  	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
  2623  		return
  2624  	}
  2625  	if rsa.Addr.Family != AF_UNSPEC {
  2626  		from, err = anyToSockaddr(fd, &rsa)
  2627  	}
  2628  	return
  2629  }
  2630  
  2631  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
  2632  	ptr, n, err := to.sockaddr()
  2633  	if err != nil {
  2634  		return err
  2635  	}
  2636  	return sendto(fd, p, flags, ptr, n)
  2637  }
  2638  
  2639  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
  2640  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
  2641  }
  2642  
  2643  func SetsockoptInt(fd, level, opt int, value int) (err error) {
  2644  	var n = int32(value)
  2645  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
  2646  }
  2647  
  2648  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
  2649  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
  2650  }
  2651  
  2652  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
  2653  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
  2654  }
  2655  
  2656  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
  2657  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
  2658  }
  2659  
  2660  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
  2661  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
  2662  }
  2663  
  2664  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
  2665  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
  2666  }
  2667  
  2668  func SetsockoptString(fd, level, opt int, s string) (err error) {
  2669  	var p unsafe.Pointer
  2670  	if len(s) > 0 {
  2671  		p = unsafe.Pointer(&[]byte(s)[0])
  2672  	}
  2673  	return setsockopt(fd, level, opt, p, uintptr(len(s)))
  2674  }
  2675  
  2676  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
  2677  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
  2678  }
  2679  
  2680  func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
  2681  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
  2682  }
  2683  
  2684  func Socket(domain, typ, proto int) (fd int, err error) {
  2685  	if domain == AF_INET6 && SocketDisableIPv6 {
  2686  		return -1, EAFNOSUPPORT
  2687  	}
  2688  	fd, err = socket(domain, typ, proto)
  2689  	return
  2690  }
  2691  
  2692  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
  2693  	var fdx [2]int32
  2694  	err = socketpair(domain, typ, proto, &fdx)
  2695  	if err == nil {
  2696  		fd[0] = int(fdx[0])
  2697  		fd[1] = int(fdx[1])
  2698  	}
  2699  	return
  2700  }
  2701  
  2702  var ioSync int64
  2703  
  2704  func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
  2705  
  2706  func SetNonblock(fd int, nonblocking bool) (err error) {
  2707  	flag, err := fcntl(fd, F_GETFL, 0)
  2708  	if err != nil {
  2709  		return err
  2710  	}
  2711  	if nonblocking {
  2712  		flag |= O_NONBLOCK
  2713  	} else {
  2714  		flag &= ^O_NONBLOCK
  2715  	}
  2716  	_, err = fcntl(fd, F_SETFL, flag)
  2717  	return err
  2718  }
  2719  
  2720  // Exec calls execve(2), which replaces the calling executable in the process
  2721  // tree. argv0 should be the full path to an executable ("/bin/ls") and the
  2722  // executable name should also be the first argument in argv (["ls", "-l"]).
  2723  // envv are the environment variables that should be passed to the new
  2724  // process (["USER=go", "PWD=/tmp"]).
  2725  func Exec(argv0 string, argv []string, envv []string) error {
  2726  	return syscall.Exec(argv0, argv, envv)
  2727  }
  2728  
  2729  func Getag(path string) (ccsid uint16, flag uint16, err error) {
  2730  	var val [8]byte
  2731  	sz, err := Getxattr(path, "ccsid", val[:])
  2732  	if err != nil {
  2733  		return
  2734  	}
  2735  	ccsid = uint16(EncodeData(val[0:sz]))
  2736  	sz, err = Getxattr(path, "flags", val[:])
  2737  	if err != nil {
  2738  		return
  2739  	}
  2740  	flag = uint16(EncodeData(val[0:sz]) >> 15)
  2741  	return
  2742  }
  2743  
  2744  // Mount begin
  2745  func impl_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  2746  	var _p0 *byte
  2747  	_p0, err = BytePtrFromString(source)
  2748  	if err != nil {
  2749  		return
  2750  	}
  2751  	var _p1 *byte
  2752  	_p1, err = BytePtrFromString(target)
  2753  	if err != nil {
  2754  		return
  2755  	}
  2756  	var _p2 *byte
  2757  	_p2, err = BytePtrFromString(fstype)
  2758  	if err != nil {
  2759  		return
  2760  	}
  2761  	var _p3 *byte
  2762  	_p3, err = BytePtrFromString(data)
  2763  	if err != nil {
  2764  		return
  2765  	}
  2766  	runtime.EnterSyscall()
  2767  	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)))
  2768  	runtime.ExitSyscall()
  2769  	if int64(r0) == -1 {
  2770  		err = errnoErr2(e1, e2)
  2771  	}
  2772  	return
  2773  }
  2774  
  2775  //go:nosplit
  2776  func get_MountAddr() *(func(source string, target string, fstype string, flags uintptr, data string) (err error))
  2777  
  2778  var Mount = enter_Mount
  2779  
  2780  func enter_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  2781  	funcref := get_MountAddr()
  2782  	if validMount() {
  2783  		*funcref = impl_Mount
  2784  	} else {
  2785  		*funcref = legacyMount
  2786  	}
  2787  	return (*funcref)(source, target, fstype, flags, data)
  2788  }
  2789  
  2790  func legacyMount(source string, target string, fstype string, flags uintptr, data string) (err error) {
  2791  	if needspace := 8 - len(fstype); needspace <= 0 {
  2792  		fstype = fstype[0:8]
  2793  	} else {
  2794  		fstype += "        "[0:needspace]
  2795  	}
  2796  	return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
  2797  }
  2798  
  2799  func validMount() bool {
  2800  	if funcptrtest(GetZosLibVec()+SYS___MOUNT1_A<<4, "") == 0 {
  2801  		if name, err := getLeFuncName(GetZosLibVec() + SYS___MOUNT1_A<<4); err == nil {
  2802  			return name == "__mount1_a"
  2803  		}
  2804  	}
  2805  	return false
  2806  }
  2807  
  2808  // Mount end
  2809  
  2810  // Unmount begin
  2811  func impl_Unmount(target string, flags int) (err error) {
  2812  	var _p0 *byte
  2813  	_p0, err = BytePtrFromString(target)
  2814  	if err != nil {
  2815  		return
  2816  	}
  2817  	runtime.EnterSyscall()
  2818  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UMOUNT2_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(flags))
  2819  	runtime.ExitSyscall()
  2820  	if int64(r0) == -1 {
  2821  		err = errnoErr2(e1, e2)
  2822  	}
  2823  	return
  2824  }
  2825  
  2826  //go:nosplit
  2827  func get_UnmountAddr() *(func(target string, flags int) (err error))
  2828  
  2829  var Unmount = enter_Unmount
  2830  
  2831  func enter_Unmount(target string, flags int) (err error) {
  2832  	funcref := get_UnmountAddr()
  2833  	if funcptrtest(GetZosLibVec()+SYS___UMOUNT2_A<<4, "") == 0 {
  2834  		*funcref = impl_Unmount
  2835  	} else {
  2836  		*funcref = legacyUnmount
  2837  	}
  2838  	return (*funcref)(target, flags)
  2839  }
  2840  
  2841  func legacyUnmount(name string, mtm int) (err error) {
  2842  	// mountpoint is always a full path and starts with a '/'
  2843  	// check if input string is not a mountpoint but a filesystem name
  2844  	if name[0] != '/' {
  2845  		return unmount_LE(name, mtm)
  2846  	}
  2847  	// treat name as mountpoint
  2848  	b2s := func(arr []byte) string {
  2849  		var str string
  2850  		for i := 0; i < len(arr); i++ {
  2851  			if arr[i] == 0 {
  2852  				str = string(arr[:i])
  2853  				break
  2854  			}
  2855  		}
  2856  		return str
  2857  	}
  2858  	var buffer struct {
  2859  		header W_Mnth
  2860  		fsinfo [64]W_Mntent
  2861  	}
  2862  	fs_count, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
  2863  	if err == nil {
  2864  		err = EINVAL
  2865  		for i := 0; i < fs_count; i++ {
  2866  			if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
  2867  				err = unmount_LE(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
  2868  				break
  2869  			}
  2870  		}
  2871  	} else if fs_count == 0 {
  2872  		err = EINVAL
  2873  	}
  2874  	return err
  2875  }
  2876  
  2877  // Unmount end
  2878  
  2879  func direntIno(buf []byte) (uint64, bool) {
  2880  	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
  2881  }
  2882  
  2883  func direntReclen(buf []byte) (uint64, bool) {
  2884  	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
  2885  }
  2886  
  2887  func direntNamlen(buf []byte) (uint64, bool) {
  2888  	reclen, ok := direntReclen(buf)
  2889  	if !ok {
  2890  		return 0, false
  2891  	}
  2892  	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
  2893  }
  2894  
  2895  func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
  2896  	var d Dirent
  2897  
  2898  	d.Ino = uint64(dirent.Ino)
  2899  	offset, err := Telldir(dir)
  2900  	if err != nil {
  2901  		return d, err
  2902  	}
  2903  
  2904  	d.Off = int64(offset)
  2905  	s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
  2906  	copy(d.Name[:], s)
  2907  
  2908  	d.Reclen = uint16(24 + len(d.NameString()))
  2909  	var st Stat_t
  2910  	path = path + "/" + s
  2911  	err = Lstat(path, &st)
  2912  	if err != nil {
  2913  		return d, err
  2914  	}
  2915  
  2916  	d.Type = uint8(st.Mode >> 24)
  2917  	return d, err
  2918  }
  2919  
  2920  func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
  2921  	// Simulation of Getdirentries port from the Darwin implementation.
  2922  	// COMMENTS FROM DARWIN:
  2923  	// It's not the full required semantics, but should handle the case
  2924  	// of calling Getdirentries or ReadDirent repeatedly.
  2925  	// It won't handle assigning the results of lseek to *basep, or handle
  2926  	// the directory being edited underfoot.
  2927  
  2928  	skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
  2929  	if err != nil {
  2930  		return 0, err
  2931  	}
  2932  
  2933  	// Get path from fd to avoid unavailable call (fdopendir)
  2934  	path, err := ZosFdToPath(fd)
  2935  	if err != nil {
  2936  		return 0, err
  2937  	}
  2938  	d, err := Opendir(path)
  2939  	if err != nil {
  2940  		return 0, err
  2941  	}
  2942  	defer Closedir(d)
  2943  
  2944  	var cnt int64
  2945  	for {
  2946  		var entryLE direntLE
  2947  		var entrypLE *direntLE
  2948  		e := Readdir_r(d, &entryLE, &entrypLE)
  2949  		if e != nil {
  2950  			return n, e
  2951  		}
  2952  		if entrypLE == nil {
  2953  			break
  2954  		}
  2955  		if skip > 0 {
  2956  			skip--
  2957  			cnt++
  2958  			continue
  2959  		}
  2960  
  2961  		// Dirent on zos has a different structure
  2962  		entry, e := direntLeToDirentUnix(&entryLE, d, path)
  2963  		if e != nil {
  2964  			return n, e
  2965  		}
  2966  
  2967  		reclen := int(entry.Reclen)
  2968  		if reclen > len(buf) {
  2969  			// Not enough room. Return for now.
  2970  			// The counter will let us know where we should start up again.
  2971  			// Note: this strategy for suspending in the middle and
  2972  			// restarting is O(n^2) in the length of the directory. Oh well.
  2973  			break
  2974  		}
  2975  
  2976  		// Copy entry into return buffer.
  2977  		s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
  2978  		copy(buf, s)
  2979  
  2980  		buf = buf[reclen:]
  2981  		n += reclen
  2982  		cnt++
  2983  	}
  2984  	// Set the seek offset of the input fd to record
  2985  	// how many files we've already returned.
  2986  	_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
  2987  	if err != nil {
  2988  		return n, err
  2989  	}
  2990  
  2991  	return n, nil
  2992  }
  2993  
  2994  func Err2ad() (eadd *int) {
  2995  	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERR2AD<<4)
  2996  	eadd = (*int)(unsafe.Pointer(r0))
  2997  	return
  2998  }
  2999  
  3000  func ZosConsolePrintf(format string, v ...interface{}) (int, error) {
  3001  	type __cmsg struct {
  3002  		_            uint16
  3003  		_            [2]uint8
  3004  		__msg_length uint32
  3005  		__msg        uintptr
  3006  		_            [4]uint8
  3007  	}
  3008  	msg := fmt.Sprintf(format, v...)
  3009  	strptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&msg)).Data)
  3010  	len := (*reflect.StringHeader)(unsafe.Pointer(&msg)).Len
  3011  	cmsg := __cmsg{__msg_length: uint32(len), __msg: uintptr(strptr)}
  3012  	cmd := uint32(0)
  3013  	runtime.EnterSyscall()
  3014  	rc, err2, err1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____CONSOLE_A<<4, uintptr(unsafe.Pointer(&cmsg)), 0, uintptr(unsafe.Pointer(&cmd)))
  3015  	runtime.ExitSyscall()
  3016  	if rc != 0 {
  3017  		return 0, fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
  3018  	}
  3019  	return 0, nil
  3020  }
  3021  func ZosStringToEbcdicBytes(str string, nullterm bool) (ebcdicBytes []byte) {
  3022  	if nullterm {
  3023  		ebcdicBytes = []byte(str + "\x00")
  3024  	} else {
  3025  		ebcdicBytes = []byte(str)
  3026  	}
  3027  	A2e(ebcdicBytes)
  3028  	return
  3029  }
  3030  func ZosEbcdicBytesToString(b []byte, trimRight bool) (str string) {
  3031  	res := make([]byte, len(b))
  3032  	copy(res, b)
  3033  	E2a(res)
  3034  	if trimRight {
  3035  		str = string(bytes.TrimRight(res, " \x00"))
  3036  	} else {
  3037  		str = string(res)
  3038  	}
  3039  	return
  3040  }
  3041  
  3042  func fdToPath(dirfd int) (path string, err error) {
  3043  	var buffer [1024]byte
  3044  	// w_ctrl()
  3045  	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
  3046  		[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
  3047  	if ret == 0 {
  3048  		zb := bytes.IndexByte(buffer[:], 0)
  3049  		if zb == -1 {
  3050  			zb = len(buffer)
  3051  		}
  3052  		// __e2a_l()
  3053  		runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
  3054  			[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
  3055  		return string(buffer[:zb]), nil
  3056  	}
  3057  	// __errno()
  3058  	errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
  3059  		[]uintptr{}))))
  3060  	// __errno2()
  3061  	errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
  3062  		[]uintptr{}))
  3063  	// strerror_r()
  3064  	ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
  3065  		[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
  3066  	if ret == 0 {
  3067  		zb := bytes.IndexByte(buffer[:], 0)
  3068  		if zb == -1 {
  3069  			zb = len(buffer)
  3070  		}
  3071  		return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
  3072  	} else {
  3073  		return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
  3074  	}
  3075  }
  3076  
  3077  func impl_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
  3078  	var _p0 *byte
  3079  	_p0, err = BytePtrFromString(path)
  3080  	if err != nil {
  3081  		return
  3082  	}
  3083  	runtime.EnterSyscall()
  3084  	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFOAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
  3085  	runtime.ExitSyscall()
  3086  	if int64(r0) == -1 {
  3087  		err = errnoErr2(e1, e2)
  3088  	}
  3089  	return
  3090  }
  3091  
  3092  //go:nosplit
  3093  func get_MkfifoatAddr() *(func(dirfd int, path string, mode uint32) (err error))
  3094  
  3095  var Mkfifoat = enter_Mkfifoat
  3096  
  3097  func enter_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
  3098  	funcref := get_MkfifoatAddr()
  3099  	if funcptrtest(GetZosLibVec()+SYS___MKFIFOAT_A<<4, "") == 0 {
  3100  		*funcref = impl_Mkfifoat
  3101  	} else {
  3102  		*funcref = legacy_Mkfifoat
  3103  	}
  3104  	return (*funcref)(dirfd, path, mode)
  3105  }
  3106  
  3107  func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
  3108  	dirname, err := ZosFdToPath(dirfd)
  3109  	if err != nil {
  3110  		return err
  3111  	}
  3112  	return Mkfifo(dirname+"/"+path, mode)
  3113  }
  3114  
  3115  //sys	Posix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT
  3116  //sys	Grantpt(fildes int) (rc int, err error) = SYS_GRANTPT
  3117  //sys	Unlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT
  3118  

View as plain text