mirror-to-gitea/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
vendor/golang.org/x/sys/unix/syscall_zos_s390x.goRaw
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}