src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

syscall_zos_s390x.go (88760B)


      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 }