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

View as plain text