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