usb-ks

USB Killswitch
git clone git://git.laack.co/usb-ks.git
Log | Files | Refs | README | LICENSE

syscall_zos_s390x.go (50177B)


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