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