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.
22
O_CLOEXEC = 0 // Dummy value (not supported).
23
AF_LOCAL = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
26
func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
27
func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
28
func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
29
func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
30
func syscall_syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
31
func syscall_rawsyscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
33
func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
34
stat.Dev = uint64(statLE.Dev)
35
stat.Ino = uint64(statLE.Ino)
36
stat.Nlink = uint64(statLE.Nlink)
37
stat.Mode = uint32(statLE.Mode)
38
stat.Uid = uint32(statLE.Uid)
39
stat.Gid = uint32(statLE.Gid)
40
stat.Rdev = uint64(statLE.Rdev)
41
stat.Size = statLE.Size
42
stat.Atim.Sec = int64(statLE.Atim)
43
stat.Atim.Nsec = 0 //zos doesn't return nanoseconds
44
stat.Mtim.Sec = int64(statLE.Mtim)
45
stat.Mtim.Nsec = 0 //zos doesn't return nanoseconds
46
stat.Ctim.Sec = int64(statLE.Ctim)
47
stat.Ctim.Nsec = 0 //zos doesn't return nanoseconds
48
stat.Blksize = int64(statLE.Blksize)
49
stat.Blocks = statLE.Blocks
52
func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
53
func svcLoad(name *byte) unsafe.Pointer
54
func svcUnload(name *byte, fnptr unsafe.Pointer) int64
56
func (d *Dirent) NameString() string {
60
s := string(d.Name[:])
61
idx := strings.IndexByte(s, 0)
69
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
70
if sa.Port < 0 || sa.Port > 0xFFFF {
73
sa.raw.Len = SizeofSockaddrInet4
74
sa.raw.Family = AF_INET
75
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
76
p[0] = byte(sa.Port >> 8)
79
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
82
func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
83
if sa.Port < 0 || sa.Port > 0xFFFF {
86
sa.raw.Len = SizeofSockaddrInet6
87
sa.raw.Family = AF_INET6
88
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
89
p[0] = byte(sa.Port >> 8)
91
sa.raw.Scope_id = sa.ZoneId
93
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
96
func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
99
if n >= len(sa.raw.Path) || n == 0 {
100
return nil, 0, EINVAL
102
sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
103
sa.raw.Family = AF_UNIX
104
for i := 0; i < n; i++ {
105
sa.raw.Path[i] = int8(name[i])
107
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
110
func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
111
// TODO(neeilan): Implement use of first param (fd)
112
switch rsa.Addr.Family {
114
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
115
sa := new(SockaddrUnix)
116
// For z/OS, only replace NUL with @ when the
117
// length is not zero.
118
if pp.Len != 0 && pp.Path[0] == 0 {
119
// "Abstract" Unix domain socket.
120
// Rewrite leading NUL as @ for textual display.
121
// (This is the standard convention.)
122
// Not friendly to overwrite in place,
123
// but the callers below don't care.
127
// Assume path ends at NUL.
129
// For z/OS, the length of the name is a field
130
// in the structure. To be on the safe side, we
131
// will still scan the name for a NUL but only
132
// to the length provided in the structure.
134
// This is not technically the Linux semantics for
135
// abstract Unix domain sockets--they are supposed
136
// to be uninterpreted fixed-size binary blobs--but
137
// everyone uses this convention.
139
for n < int(pp.Len) && pp.Path[n] != 0 {
142
sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
146
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
147
sa := new(SockaddrInet4)
148
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
149
sa.Port = int(p[0])<<8 + int(p[1])
154
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
155
sa := new(SockaddrInet6)
156
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
157
sa.Port = int(p[0])<<8 + int(p[1])
158
sa.ZoneId = pp.Scope_id
162
return nil, EAFNOSUPPORT
165
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
166
var rsa RawSockaddrAny
167
var len _Socklen = SizeofSockaddrAny
168
nfd, err = accept(fd, &rsa, &len)
172
// TODO(neeilan): Remove 0 in call
173
sa, err = anyToSockaddr(0, &rsa)
181
func (iov *Iovec) SetLen(length int) {
182
iov.Len = uint64(length)
185
func (msghdr *Msghdr) SetControllen(length int) {
186
msghdr.Controllen = int32(length)
189
func (cmsg *Cmsghdr) SetLen(length int) {
190
cmsg.Len = int32(length)
193
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
194
//sys read(fd int, p []byte) (n int, err error)
195
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
196
//sys write(fd int, p []byte) (n int, err error)
198
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A
199
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A
200
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A
201
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
202
//sysnb setgroups(n int, list *_Gid_t) (err error)
203
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
204
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
205
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
206
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
207
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A
208
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A
209
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A
210
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A
211
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A
212
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A
213
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP
214
//sys munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP
215
//sys ioctl(fd int, req int, arg uintptr) (err error) = SYS_IOCTL
216
//sys ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = SYS_IOCTL
218
//sys Access(path string, mode uint32) (err error) = SYS___ACCESS_A
219
//sys Chdir(path string) (err error) = SYS___CHDIR_A
220
//sys Chown(path string, uid int, gid int) (err error) = SYS___CHOWN_A
221
//sys Chmod(path string, mode uint32) (err error) = SYS___CHMOD_A
222
//sys Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A
223
//sys Dup(oldfd int) (fd int, err error)
224
//sys Dup2(oldfd int, newfd int) (err error)
225
//sys Errno2() (er2 int) = SYS___ERRNO2
226
//sys Err2ad() (eadd *int) = SYS___ERR2AD
228
//sys Fchdir(fd int) (err error)
229
//sys Fchmod(fd int, mode uint32) (err error)
230
//sys Fchown(fd int, uid int, gid int) (err error)
231
//sys FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) = SYS_FCNTL
232
//sys fstat(fd int, stat *Stat_LE_t) (err error)
234
func Fstat(fd int, stat *Stat_t) (err error) {
236
err = fstat(fd, &statLE)
237
copyStat(stat, &statLE)
241
//sys Fstatvfs(fd int, stat *Statvfs_t) (err error) = SYS_FSTATVFS
242
//sys Fsync(fd int) (err error)
243
//sys Ftruncate(fd int, length int64) (err error)
244
//sys Getpagesize() (pgsize int) = SYS_GETPAGESIZE
245
//sys Mprotect(b []byte, prot int) (err error) = SYS_MPROTECT
246
//sys Msync(b []byte, flags int) (err error) = SYS_MSYNC
247
//sys Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL
248
//sys Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES
249
//sys W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT
250
//sys W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A
252
//sys mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
253
//sys unmount(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
254
//sys Chroot(path string) (err error) = SYS___CHROOT_A
255
//sys Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT
256
//sysnb Uname(buf *Utsname) (err error) = SYS___UNAME_A
258
func Ptsname(fd int) (name string, err error) {
259
r0, _, e1 := syscall_syscall(SYS___PTSNAME_A, uintptr(fd), 0, 0)
260
name = u2s(unsafe.Pointer(r0))
267
func u2s(cstr unsafe.Pointer) string {
268
str := (*[1024]uint8)(cstr)
273
return string(str[:i])
276
func Close(fd int) (err error) {
277
_, _, e1 := syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
278
for i := 0; e1 == EAGAIN && i < 10; i++ {
279
_, _, _ = syscall_syscall(SYS_USLEEP, uintptr(10), 0, 0)
280
_, _, e1 = syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
288
var mapper = &mmapper{
289
active: make(map[*byte][]byte),
294
// Dummy function: there are no semantics for Madvise on z/OS
295
func Madvise(b []byte, advice int) (err error) {
299
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
300
return mapper.Mmap(fd, offset, length, prot, flags)
303
func Munmap(b []byte) (err error) {
304
return mapper.Munmap(b)
307
//sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
308
//sysnb Getegid() (egid int)
309
//sysnb Geteuid() (uid int)
310
//sysnb Getgid() (gid int)
311
//sysnb Getpid() (pid int)
312
//sysnb Getpgid(pid int) (pgid int, err error) = SYS_GETPGID
314
func Getpgrp() (pid int) {
319
//sysnb Getppid() (pid int)
320
//sys Getpriority(which int, who int) (prio int, err error)
321
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT
323
//sysnb getrusage(who int, rusage *rusage_zos) (err error) = SYS_GETRUSAGE
325
func Getrusage(who int, rusage *Rusage) (err error) {
327
err = getrusage(who, &ruz)
328
//Only the first two fields of Rusage are set
329
rusage.Utime.Sec = ruz.Utime.Sec
330
rusage.Utime.Usec = int64(ruz.Utime.Usec)
331
rusage.Stime.Sec = ruz.Stime.Sec
332
rusage.Stime.Usec = int64(ruz.Stime.Usec)
336
//sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID
337
//sysnb Getuid() (uid int)
338
//sysnb Kill(pid int, sig Signal) (err error)
339
//sys Lchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A
340
//sys Link(path string, link string) (err error) = SYS___LINK_A
341
//sys Listen(s int, n int) (err error)
342
//sys lstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A
344
func Lstat(path string, stat *Stat_t) (err error) {
346
err = lstat(path, &statLE)
347
copyStat(stat, &statLE)
351
//sys Mkdir(path string, mode uint32) (err error) = SYS___MKDIR_A
352
//sys Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A
353
//sys Mknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A
354
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
355
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
356
//sys Readlink(path string, buf []byte) (n int, err error) = SYS___READLINK_A
357
//sys Rename(from string, to string) (err error) = SYS___RENAME_A
358
//sys Rmdir(path string) (err error) = SYS___RMDIR_A
359
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
360
//sys Setpriority(which int, who int, prio int) (err error)
361
//sysnb Setpgid(pid int, pgid int) (err error) = SYS_SETPGID
362
//sysnb Setrlimit(resource int, lim *Rlimit) (err error)
363
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID
364
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID
365
//sysnb Setsid() (pid int, err error) = SYS_SETSID
366
//sys Setuid(uid int) (err error) = SYS_SETUID
367
//sys Setgid(uid int) (err error) = SYS_SETGID
368
//sys Shutdown(fd int, how int) (err error)
369
//sys stat(path string, statLE *Stat_LE_t) (err error) = SYS___STAT_A
371
func Stat(path string, sta *Stat_t) (err error) {
373
err = stat(path, &statLE)
374
copyStat(sta, &statLE)
378
//sys Symlink(path string, link string) (err error) = SYS___SYMLINK_A
379
//sys Sync() = SYS_SYNC
380
//sys Truncate(path string, length int64) (err error) = SYS___TRUNCATE_A
381
//sys Tcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR
382
//sys Tcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR
383
//sys Umask(mask int) (oldmask int)
384
//sys Unlink(path string) (err error) = SYS___UNLINK_A
385
//sys Utime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A
387
//sys open(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A
389
func Open(path string, mode int, perm uint32) (fd int, err error) {
390
return open(path, mode, perm)
393
func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
399
if err := Fchdir(dirfd); err != nil {
404
return Mkfifo(path, mode)
407
//sys remove(path string) (err error)
409
func Remove(path string) error {
413
const ImplementsGetwd = true
415
func Getcwd(buf []byte) (n int, err error) {
418
p = unsafe.Pointer(&buf[0])
420
p = unsafe.Pointer(&_zero)
422
_, _, e := syscall_syscall(SYS___GETCWD_A, uintptr(p), uintptr(len(buf)), 0)
430
func Getwd() (wd string, err error) {
431
var buf [PathMax]byte
432
n, err := Getcwd(buf[0:])
436
// Getcwd returns the number of bytes written to buf, including the NUL.
437
if n < 1 || n > len(buf) || buf[n-1] != 0 {
440
return string(buf[0 : n-1]), nil
443
func Getgroups() (gids []int, err error) {
444
n, err := getgroups(0, nil)
452
// Sanity check group count. Max is 1<<16 on Linux.
453
if n < 0 || n > 1<<20 {
457
a := make([]_Gid_t, n)
458
n, err = getgroups(n, &a[0])
462
gids = make([]int, n)
463
for i, v := range a[0:n] {
469
func Setgroups(gids []int) (err error) {
471
return setgroups(0, nil)
474
a := make([]_Gid_t, len(gids))
475
for i, v := range gids {
478
return setgroups(len(a), &a[0])
483
func Gettid() (tid int) {
487
type WaitStatus uint32
489
// Wait status is 7 bits at bottom, either 0 (exited),
490
// 0x7F (stopped), or a signal number that caused an exit.
491
// The 0x80 bit is whether there was a core dump.
492
// An extra number (exit code, signal causing a stop)
493
// is in the high bits. At least that's the idea.
494
// There are various irregularities. For example, the
495
// "continued" status is 0xFFFF, distinguishing itself
496
// from stopped via the core dump bit.
506
func (w WaitStatus) Exited() bool { return w&mask == exited }
508
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
510
func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
512
func (w WaitStatus) Continued() bool { return w == 0xFFFF }
514
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
516
func (w WaitStatus) ExitStatus() int {
520
return int(w>>shift) & 0xFF
523
func (w WaitStatus) Signal() Signal {
527
return Signal(w & mask)
530
func (w WaitStatus) StopSignal() Signal {
534
return Signal(w>>shift) & 0xFF
537
func (w WaitStatus) TrapCause() int { return -1 }
539
//sys waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)
541
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
542
// TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.
543
// At the moment rusage will not be touched.
545
wpid, err = waitpid(pid, &status, options)
547
*wstatus = WaitStatus(status)
552
//sysnb gettimeofday(tv *timeval_zos) (err error)
554
func Gettimeofday(tv *Timeval) (err error) {
556
err = gettimeofday(&tvz)
558
tv.Usec = int64(tvz.Usec)
562
func Time(t *Time_t) (tt Time_t, err error) {
564
err = Gettimeofday(&tv)
571
return Time_t(tv.Sec), nil
574
func setTimespec(sec, nsec int64) Timespec {
575
return Timespec{Sec: sec, Nsec: nsec}
578
func setTimeval(sec, usec int64) Timeval { //fix
579
return Timeval{Sec: sec, Usec: usec}
582
//sysnb pipe(p *[2]_C_int) (err error)
584
func Pipe(p []int) (err error) {
597
//sys utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
599
func Utimes(path string, tv []Timeval) (err error) {
603
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
606
func UtimesNano(path string, ts []Timespec) error {
610
// Not as efficient as it could be because Timespec and
611
// Timeval have different types in the different OSes
613
NsecToTimeval(TimespecToNsec(ts[0])),
614
NsecToTimeval(TimespecToNsec(ts[1])),
616
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
619
func Getsockname(fd int) (sa Sockaddr, err error) {
620
var rsa RawSockaddrAny
621
var len _Socklen = SizeofSockaddrAny
622
if err = getsockname(fd, &rsa, &len); err != nil {
625
// TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )
626
return anyToSockaddr(0, &rsa)
630
// identifier constants
631
nwmHeaderIdentifier = 0xd5e6d4c8
632
nwmFilterIdentifier = 0xd5e6d4c6
633
nwmTCPConnIdentifier = 0xd5e6d4c3
634
nwmRecHeaderIdentifier = 0xd5e6d4d9
635
nwmIPStatsIdentifier = 0xd5e6d4c9d7e2e340
636
nwmIPGStatsIdentifier = 0xd5e6d4c9d7c7e2e3
637
nwmTCPStatsIdentifier = 0xd5e6d4e3c3d7e2e3
638
nwmUDPStatsIdentifier = 0xd5e6d4e4c4d7e2e3
639
nwmICMPGStatsEntry = 0xd5e6d4c9c3d4d7c7
640
nwmICMPTStatsEntry = 0xd5e6d4c9c3d4d7e3
642
// nwmHeader constants
648
nwmGlobalStatsType = 14
650
// nwmFilter constants
651
nwmFilterLclAddrMask = 0x20000000 // Local address
652
nwmFilterSrcAddrMask = 0x20000000 // Source address
653
nwmFilterLclPortMask = 0x10000000 // Local port
654
nwmFilterSrcPortMask = 0x10000000 // Source port
656
// nwmConnEntry constants
657
nwmTCPStateClosed = 1
658
nwmTCPStateListen = 2
659
nwmTCPStateSynSent = 3
660
nwmTCPStateSynRcvd = 4
662
nwmTCPStateFinWait1 = 6
663
nwmTCPStateFinWait2 = 7
664
nwmTCPStateClosWait = 8
665
nwmTCPStateLastAck = 9
666
nwmTCPStateClosing = 10
667
nwmTCPStateTimeWait = 11
668
nwmTCPStateDeletTCB = 12
670
// Existing constants on linux
675
BPF_TCP_ESTABLISHED = 5
676
BPF_TCP_FIN_WAIT1 = 6
677
BPF_TCP_FIN_WAIT2 = 7
678
BPF_TCP_CLOSE_WAIT = 8
681
BPF_TCP_TIME_WAIT = 11
682
BPF_TCP_NEW_SYN_RECV = -1
683
BPF_TCP_MAX_STATES = -2
686
type nwmTriplet struct {
692
type nwmQuadruplet struct {
699
type nwmHeader struct {
708
outputDesc nwmQuadruplet
711
type nwmFilter struct {
717
local [28]byte // union of sockaddr4 and sockaddr6
718
remote [28]byte // union of sockaddr4 and sockaddr6
744
type nwmRecHeader struct {
751
type nwmTCPStatsEntry struct {
760
timeWaitReused uint32
769
inAllBeforeWin uint32
770
inSomeBeforeWin uint32
772
inSomeAfterWin uint32
782
retransTimeouts uint32
788
keepAliveProbes uint32
789
keepAliveDrops uint32
802
smcRCurrEstabLnks uint32
803
smcRLnkActTimeOut uint32
804
smcRActLnkOpened uint32
805
smcRPasLnkOpened uint32
806
smcRLnksClosed uint32
808
smcRActiveOpened uint32
809
smcRPassiveOpened uint32
810
smcRConnClosed uint32
815
smcDCurrEstabLnks uint32
816
smcDActLnkOpened uint32
817
smcDPasLnkOpened uint32
818
smcDLnksClosed uint32
820
smcDActiveOpened uint32
821
smcDPassiveOpened uint32
822
smcDConnClosed uint32
829
type nwmConnEntry struct {
831
local [28]byte // union of sockaddr4 and sockaddr6
832
remote [28]byte // union of sockaddr4 and sockaddr6
833
startTime [8]byte // uint64, changed to prevent padding from being inserted
834
lastActivity [8]byte // uint64
835
bytesIn [8]byte // uint64
836
bytesOut [8]byte // uint64
837
inSegs [8]byte // uint64
838
outSegs [8]byte // uint64
854
outOfOrderCount uint32
855
lcl0WindowCount uint32
856
rmt0WindowCount uint32
874
serverResourceId uint32
884
inOldestTime [8]byte // uint64
885
outOldestTime [8]byte // uint64
886
tcpTrustedPartner byte
888
bulkDataIntfName [16]byte
906
var svcNameTable [][]byte = [][]byte{
907
[]byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"), // svc_EZBNMIF4
914
func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
915
jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40") // "*"
916
responseBuffer := [4096]byte{0}
917
var bufferAlet, reasonCode uint32 = 0, 0
918
var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
921
var argv [7]unsafe.Pointer
922
argv[0] = unsafe.Pointer(&jobname[0])
923
argv[1] = unsafe.Pointer(&responseBuffer[0])
924
argv[2] = unsafe.Pointer(&bufferAlet)
925
argv[3] = unsafe.Pointer(&bufferLen)
926
argv[4] = unsafe.Pointer(&returnValue)
927
argv[5] = unsafe.Pointer(&returnCode)
928
argv[6] = unsafe.Pointer(&reasonCode)
930
request := (*struct {
933
})(unsafe.Pointer(&responseBuffer[0]))
935
EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
937
return nil, errnoErr(EINVAL)
940
// GetGlobalStats EZBNMIF4 call
941
request.header.ident = nwmHeaderIdentifier
942
request.header.length = uint32(unsafe.Sizeof(request.header))
943
request.header.version = nwmCurrentVer
944
request.header.nwmType = nwmGlobalStatsType
945
request.header.options = 0x80000000
947
svcCall(EZBNMIF4, &argv[0], &dsa[0])
949
// outputDesc field is filled by EZBNMIF4 on success
950
if returnCode != 0 || request.header.outputDesc.offset == 0 {
951
return nil, errnoErr(EINVAL)
954
// Check that EZBNMIF4 returned a nwmRecHeader
955
recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
956
if recHeader.ident != nwmRecHeaderIdentifier {
957
return nil, errnoErr(EINVAL)
960
// Parse nwmTriplets to get offsets of returned entries
961
var sections []*uint64
962
var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
963
for i := uint32(0); i < uint32(recHeader.number); i++ {
964
offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
965
sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
966
for j := uint32(0); j < sectionDesc.number; j++ {
967
offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
968
sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
972
// Find nwmTCPStatsEntry in returned entries
973
var tcpStats *nwmTCPStatsEntry = nil
974
for _, ptr := range sections {
976
case nwmTCPStatsIdentifier:
978
return nil, errnoErr(EINVAL)
980
tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
981
case nwmIPStatsIdentifier:
982
case nwmIPGStatsIdentifier:
983
case nwmUDPStatsIdentifier:
984
case nwmICMPGStatsEntry:
985
case nwmICMPTStatsEntry:
987
return nil, errnoErr(EINVAL)
991
return nil, errnoErr(EINVAL)
994
// GetConnectionDetail EZBNMIF4 call
995
responseBuffer = [4096]byte{0}
997
bufferAlet, reasonCode = 0, 0
998
bufferLen, returnValue, returnCode = 4096, 0, 0
999
nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process
1000
nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
1001
argv[0] = unsafe.Pointer(uintptr(*nameptr))
1003
request.header.ident = nwmHeaderIdentifier
1004
request.header.length = uint32(unsafe.Sizeof(request.header))
1005
request.header.version = nwmCurrentVer
1006
request.header.nwmType = nwmTCPConnType
1007
request.header.options = 0x80000000
1009
request.filter.ident = nwmFilterIdentifier
1011
var localSockaddr RawSockaddrAny
1012
socklen := _Socklen(SizeofSockaddrAny)
1013
err := getsockname(fd, &localSockaddr, &socklen)
1015
return nil, errnoErr(EINVAL)
1017
if localSockaddr.Addr.Family == AF_INET {
1018
localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
1019
localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
1020
localSockFilter.Family = AF_INET
1022
for i = 0; i < 4; i++ {
1023
if localSockaddr.Addr[i] != 0 {
1028
request.filter.flags |= nwmFilterLclAddrMask
1029
for i = 0; i < 4; i++ {
1030
localSockFilter.Addr[i] = localSockaddr.Addr[i]
1033
if localSockaddr.Port != 0 {
1034
request.filter.flags |= nwmFilterLclPortMask
1035
localSockFilter.Port = localSockaddr.Port
1037
} else if localSockaddr.Addr.Family == AF_INET6 {
1038
localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
1039
localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
1040
localSockFilter.Family = AF_INET6
1042
for i = 0; i < 16; i++ {
1043
if localSockaddr.Addr[i] != 0 {
1048
request.filter.flags |= nwmFilterLclAddrMask
1049
for i = 0; i < 16; i++ {
1050
localSockFilter.Addr[i] = localSockaddr.Addr[i]
1053
if localSockaddr.Port != 0 {
1054
request.filter.flags |= nwmFilterLclPortMask
1055
localSockFilter.Port = localSockaddr.Port
1059
svcCall(EZBNMIF4, &argv[0], &dsa[0])
1061
// outputDesc field is filled by EZBNMIF4 on success
1062
if returnCode != 0 || request.header.outputDesc.offset == 0 {
1063
return nil, errnoErr(EINVAL)
1066
// Check that EZBNMIF4 returned a nwmConnEntry
1067
conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
1068
if conn.ident != nwmTCPConnIdentifier {
1069
return nil, errnoErr(EINVAL)
1072
// Copy data from the returned data structures into tcpInfo
1073
// Stats from nwmConnEntry are specific to that connection.
1074
// Stats from nwmTCPStatsEntry are global (to the interface?)
1075
// Fields may not be an exact match. Some fields have no equivalent.
1077
tcpinfo.State = uint8(conn.state)
1078
tcpinfo.Ca_state = 0 // dummy
1079
tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
1080
tcpinfo.Probes = uint8(tcpStats.outWinProbes)
1081
tcpinfo.Backoff = 0 // dummy
1082
tcpinfo.Options = 0 // dummy
1083
tcpinfo.Rto = tcpStats.retransTimeouts
1084
tcpinfo.Ato = tcpStats.outDelayAcks
1085
tcpinfo.Snd_mss = conn.sendMSS
1086
tcpinfo.Rcv_mss = conn.sendMSS // dummy
1087
tcpinfo.Unacked = 0 // dummy
1088
tcpinfo.Sacked = 0 // dummy
1089
tcpinfo.Lost = 0 // dummy
1090
tcpinfo.Retrans = conn.reXmtCount
1091
tcpinfo.Fackets = 0 // dummy
1092
tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
1093
tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
1094
tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
1095
tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
1096
tcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate
1097
tcpinfo.Rcv_ssthresh = conn.ssThresh
1098
tcpinfo.Rtt = conn.roundTripTime
1099
tcpinfo.Rttvar = conn.roundTripVar
1100
tcpinfo.Snd_ssthresh = conn.ssThresh // dummy
1101
tcpinfo.Snd_cwnd = conn.congestionWnd
1102
tcpinfo.Advmss = conn.sendMSS // dummy
1103
tcpinfo.Reordering = 0 // dummy
1104
tcpinfo.Rcv_rtt = conn.roundTripTime // dummy
1105
tcpinfo.Rcv_space = conn.sendMSS // dummy
1106
tcpinfo.Total_retrans = conn.reXmtCount
1108
svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
1110
return &tcpinfo, nil
1113
// GetsockoptString returns the string value of the socket option opt for the
1114
// socket associated with fd at the given socket level.
1115
func GetsockoptString(fd, level, opt int) (string, error) {
1116
buf := make([]byte, 256)
1117
vallen := _Socklen(len(buf))
1118
err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1123
return string(buf[:vallen-1]), nil
1126
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
1128
var rsa RawSockaddrAny
1129
msg.Name = (*byte)(unsafe.Pointer(&rsa))
1130
msg.Namelen = SizeofSockaddrAny
1133
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
1138
// receive at least one normal byte
1143
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
1144
msg.SetControllen(len(oob))
1148
if n, err = recvmsg(fd, &msg, flags); err != nil {
1151
oobn = int(msg.Controllen)
1152
recvflags = int(msg.Flags)
1153
// source address is only specified if the socket is unconnected
1154
if rsa.Addr.Family != AF_UNSPEC {
1155
// TODO(neeilan): Remove 0 arg added to get this compiling on z/OS
1156
from, err = anyToSockaddr(0, &rsa)
1161
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
1162
_, err = SendmsgN(fd, p, oob, to, flags)
1166
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
1167
var ptr unsafe.Pointer
1171
ptr, salen, err = to.sockaddr()
1177
msg.Name = (*byte)(unsafe.Pointer(ptr))
1178
msg.Namelen = int32(salen)
1181
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
1186
// send at least one normal byte
1191
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
1192
msg.SetControllen(len(oob))
1196
if n, err = sendmsg(fd, &msg, flags); err != nil {
1199
if len(oob) > 0 && len(p) == 0 {
1205
func Opendir(name string) (uintptr, error) {
1206
p, err := BytePtrFromString(name)
1210
dir, _, e := syscall_syscall(SYS___OPENDIR_A, uintptr(unsafe.Pointer(p)), 0, 0)
1211
runtime.KeepAlive(unsafe.Pointer(p))
1218
// clearsyscall.Errno resets the errno value to 0.
1221
func Readdir(dir uintptr) (*Dirent, error) {
1224
// __readdir_r_a returns errno at the end of the directory stream, rather than 0.
1225
// Therefore to avoid false positives we clear errno before calling it.
1227
// TODO(neeilan): Commented this out to get sys/unix compiling on z/OS. Uncomment and fix. Error: "undefined: clearsyscall"
1228
//clearsyscall.Errno() // TODO(mundaym): check pre-emption rules.
1230
e, _, _ := syscall_syscall(SYS___READDIR_R_A, dir, uintptr(unsafe.Pointer(&ent)), uintptr(unsafe.Pointer(&res)))
1233
err = errnoErr(Errno(e))
1241
func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
1242
r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
1243
if int64(r0) == -1 {
1244
err = errnoErr(Errno(e1))
1249
func Closedir(dir uintptr) error {
1250
_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
1257
func Seekdir(dir uintptr, pos int) {
1258
_, _, _ = syscall_syscall(SYS_SEEKDIR, dir, uintptr(pos), 0)
1261
func Telldir(dir uintptr) (int, error) {
1262
p, _, e := syscall_syscall(SYS_TELLDIR, dir, 0, 0)
1265
return pos, errnoErr(e)
1270
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
1271
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
1272
// struct flock is packed on z/OS. We can't emulate that in Go so
1273
// instead we pack it here.
1275
*(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
1276
*(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
1277
*(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
1278
*(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
1279
*(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
1280
_, _, errno := syscall_syscall(SYS_FCNTL, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
1281
lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
1282
lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
1283
lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
1284
lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
1285
lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
1292
func Flock(fd int, how int) error {
1294
var flock_type int16
1298
case LOCK_SH | LOCK_NB:
1299
flock_type = F_RDLCK
1301
case LOCK_EX | LOCK_NB:
1302
flock_type = F_WRLCK
1305
flock_type = F_WRLCK
1306
fcntl_cmd = F_SETLKW
1308
flock_type = F_UNLCK
1309
fcntl_cmd = F_SETLKW
1314
Type: int16(flock_type),
1318
Pid: int32(Getppid()),
1321
err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
1325
func Mlock(b []byte) (err error) {
1326
_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
1333
func Mlock2(b []byte, flags int) (err error) {
1334
_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
1341
func Mlockall(flags int) (err error) {
1342
_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
1349
func Munlock(b []byte) (err error) {
1350
_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
1357
func Munlockall() (err error) {
1358
_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
1365
func ClockGettime(clockid int32, ts *Timespec) error {
1367
var ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise
1368
var nsec_per_sec int64 = 1000000000
1373
if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
1374
var nanotime int64 = runtime.Nanotime1()
1375
ts.Sec = nanotime / nsec_per_sec
1376
ts.Nsec = nanotime % nsec_per_sec
1377
} else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
1379
_, err := Times(&tm)
1383
ts.Sec = int64(tm.Utime / ticks_per_sec)
1384
ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
1391
func Statfs(path string, stat *Statfs_t) (err error) {
1392
fd, err := open(path, O_RDONLY, 0)
1397
return Fstatfs(fd, stat)
1406
// Do the interface allocations only once for common
1409
errEAGAIN error = syscall.EAGAIN
1410
errEINVAL error = syscall.EINVAL
1411
errENOENT error = syscall.ENOENT
1415
signalNameMapOnce sync.Once
1416
signalNameMap map[string]syscall.Signal
1419
// errnoErr returns common boxed Errno values, to prevent
1420
// allocations at runtime.
1421
func errnoErr(e Errno) error {
1435
// ErrnoName returns the error name for error number e.
1436
func ErrnoName(e Errno) string {
1437
i := sort.Search(len(errorList), func(i int) bool {
1438
return errorList[i].num >= e
1440
if i < len(errorList) && errorList[i].num == e {
1441
return errorList[i].name
1446
// SignalName returns the signal name for signal number s.
1447
func SignalName(s syscall.Signal) string {
1448
i := sort.Search(len(signalList), func(i int) bool {
1449
return signalList[i].num >= s
1451
if i < len(signalList) && signalList[i].num == s {
1452
return signalList[i].name
1457
// SignalNum returns the syscall.Signal for signal named s,
1458
// or 0 if a signal with such name is not found.
1459
// The signal name should start with "SIG".
1460
func SignalNum(s string) syscall.Signal {
1461
signalNameMapOnce.Do(func() {
1462
signalNameMap = make(map[string]syscall.Signal, len(signalList))
1463
for _, signal := range signalList {
1464
signalNameMap[signal.name] = signal.num
1467
return signalNameMap[s]
1470
// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
1471
func clen(n []byte) int {
1472
i := bytes.IndexByte(n, 0)
1479
// Mmap manager, for use by operating system-specific implementations.
1481
type mmapper struct {
1483
active map[*byte][]byte // active mappings; key is last byte in mapping
1484
mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
1485
munmap func(addr uintptr, length uintptr) error
1488
func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1493
// Map the requested memory.
1494
addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
1499
// Slice memory layout
1504
}{addr, length, length}
1506
// Use unsafe to turn sl into a []byte.
1507
b := *(*[]byte)(unsafe.Pointer(&sl))
1509
// Register mapping in m and return it.
1517
func (m *mmapper) Munmap(data []byte) (err error) {
1518
if len(data) == 0 || len(data) != cap(data) {
1522
// Find the base of the mapping.
1523
p := &data[cap(data)-1]
1527
if b == nil || &b[0] != &data[0] {
1531
// Unmap the memory and update m.
1532
if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
1539
func Read(fd int, p []byte) (n int, err error) {
1540
n, err = read(fd, p)
1543
raceWriteRange(unsafe.Pointer(&p[0]), n)
1546
raceAcquire(unsafe.Pointer(&ioSync))
1552
func Write(fd int, p []byte) (n int, err error) {
1554
raceReleaseMerge(unsafe.Pointer(&ioSync))
1556
n, err = write(fd, p)
1557
if raceenabled && n > 0 {
1558
raceReadRange(unsafe.Pointer(&p[0]), n)
1563
// For testing: clients can set this flag to force
1564
// creation of IPv6 sockets to return EAFNOSUPPORT.
1565
var SocketDisableIPv6 bool
1567
// Sockaddr represents a socket address.
1568
type Sockaddr interface {
1569
sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
1572
// SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
1573
type SockaddrInet4 struct {
1576
raw RawSockaddrInet4
1579
// SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
1580
type SockaddrInet6 struct {
1584
raw RawSockaddrInet6
1587
// SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
1588
type SockaddrUnix struct {
1593
func Bind(fd int, sa Sockaddr) (err error) {
1594
ptr, n, err := sa.sockaddr()
1598
return bind(fd, ptr, n)
1601
func Connect(fd int, sa Sockaddr) (err error) {
1602
ptr, n, err := sa.sockaddr()
1606
return connect(fd, ptr, n)
1609
func Getpeername(fd int) (sa Sockaddr, err error) {
1610
var rsa RawSockaddrAny
1611
var len _Socklen = SizeofSockaddrAny
1612
if err = getpeername(fd, &rsa, &len); err != nil {
1615
return anyToSockaddr(fd, &rsa)
1618
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
1620
vallen := _Socklen(1)
1621
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
1625
func GetsockoptInt(fd, level, opt int) (value int, err error) {
1627
vallen := _Socklen(4)
1628
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
1632
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
1633
vallen := _Socklen(4)
1634
err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
1638
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
1640
vallen := _Socklen(SizeofIPMreq)
1641
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1645
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
1647
vallen := _Socklen(SizeofIPv6Mreq)
1648
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1652
func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
1653
var value IPv6MTUInfo
1654
vallen := _Socklen(SizeofIPv6MTUInfo)
1655
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1659
func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
1660
var value ICMPv6Filter
1661
vallen := _Socklen(SizeofICMPv6Filter)
1662
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
1666
func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
1668
vallen := _Socklen(SizeofLinger)
1669
err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
1673
func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
1675
vallen := _Socklen(unsafe.Sizeof(tv))
1676
err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
1680
func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
1682
vallen := _Socklen(8)
1683
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
1687
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
1688
var rsa RawSockaddrAny
1689
var len _Socklen = SizeofSockaddrAny
1690
if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
1693
if rsa.Addr.Family != AF_UNSPEC {
1694
from, err = anyToSockaddr(fd, &rsa)
1699
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
1700
ptr, n, err := to.sockaddr()
1704
return sendto(fd, p, flags, ptr, n)
1707
func SetsockoptByte(fd, level, opt int, value byte) (err error) {
1708
return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
1711
func SetsockoptInt(fd, level, opt int, value int) (err error) {
1712
var n = int32(value)
1713
return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
1716
func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
1717
return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
1720
func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
1721
return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
1724
func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
1725
return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
1728
func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
1729
return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
1732
func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
1733
return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
1736
func SetsockoptString(fd, level, opt int, s string) (err error) {
1737
var p unsafe.Pointer
1739
p = unsafe.Pointer(&[]byte(s)[0])
1741
return setsockopt(fd, level, opt, p, uintptr(len(s)))
1744
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
1745
return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
1748
func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
1749
return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
1752
func Socket(domain, typ, proto int) (fd int, err error) {
1753
if domain == AF_INET6 && SocketDisableIPv6 {
1754
return -1, EAFNOSUPPORT
1756
fd, err = socket(domain, typ, proto)
1760
func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
1762
err = socketpair(domain, typ, proto, &fdx)
1772
func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
1774
func SetNonblock(fd int, nonblocking bool) (err error) {
1775
flag, err := fcntl(fd, F_GETFL, 0)
1784
_, err = fcntl(fd, F_SETFL, flag)
1788
// Exec calls execve(2), which replaces the calling executable in the process
1789
// tree. argv0 should be the full path to an executable ("/bin/ls") and the
1790
// executable name should also be the first argument in argv (["ls", "-l"]).
1791
// envv are the environment variables that should be passed to the new
1792
// process (["USER=go", "PWD=/tmp"]).
1793
func Exec(argv0 string, argv []string, envv []string) error {
1794
return syscall.Exec(argv0, argv, envv)
1797
func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1798
if needspace := 8 - len(fstype); needspace <= 0 {
1801
fstype += " "[:needspace]
1803
return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
1806
func Unmount(name string, mtm int) (err error) {
1807
// mountpoint is always a full path and starts with a '/'
1808
// check if input string is not a mountpoint but a filesystem name
1810
return unmount(name, mtm)
1812
// treat name as mountpoint
1813
b2s := func(arr []byte) string {
1814
nulli := bytes.IndexByte(arr, 0)
1818
return string(arr[:nulli])
1825
fsCount, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
1832
for i := 0; i < fsCount; i++ {
1833
if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
1834
err = unmount(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
1841
func fdToPath(dirfd int) (path string, err error) {
1842
var buffer [1024]byte
1844
ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
1845
[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
1847
zb := bytes.IndexByte(buffer[:], 0)
1852
runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
1853
[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
1854
return string(buffer[:zb]), nil
1857
errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
1860
errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
1863
ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
1864
[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
1866
zb := bytes.IndexByte(buffer[:], 0)
1870
return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
1872
return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
1876
func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
1879
d.Ino = uint64(dirent.Ino)
1880
offset, err := Telldir(dir)
1885
d.Off = int64(offset)
1886
s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
1889
d.Reclen = uint16(24 + len(d.NameString()))
1891
path = path + "/" + s
1892
err = Lstat(path, &st)
1897
d.Type = uint8(st.Mode >> 24)
1901
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
1902
// Simulation of Getdirentries port from the Darwin implementation.
1903
// COMMENTS FROM DARWIN:
1904
// It's not the full required semantics, but should handle the case
1905
// of calling Getdirentries or ReadDirent repeatedly.
1906
// It won't handle assigning the results of lseek to *basep, or handle
1907
// the directory being edited underfoot.
1909
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
1914
// Get path from fd to avoid unavailable call (fdopendir)
1915
path, err := fdToPath(fd)
1919
d, err := Opendir(path)
1927
var entryLE direntLE
1928
var entrypLE *direntLE
1929
e := readdir_r(d, &entryLE, &entrypLE)
1933
if entrypLE == nil {
1942
// Dirent on zos has a different structure
1943
entry, e := direntLeToDirentUnix(&entryLE, d, path)
1948
reclen := int(entry.Reclen)
1949
if reclen > len(buf) {
1950
// Not enough room. Return for now.
1951
// The counter will let us know where we should start up again.
1952
// Note: this strategy for suspending in the middle and
1953
// restarting is O(n^2) in the length of the directory. Oh well.
1957
// Copy entry into return buffer.
1958
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
1965
// Set the seek offset of the input fd to record
1966
// how many files we've already returned.
1967
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
1975
func ReadDirent(fd int, buf []byte) (n int, err error) {
1976
var base = (*uintptr)(unsafe.Pointer(new(uint64)))
1977
return Getdirentries(fd, buf, base)
1980
func direntIno(buf []byte) (uint64, bool) {
1981
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1984
func direntReclen(buf []byte) (uint64, bool) {
1985
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1988
func direntNamlen(buf []byte) (uint64, bool) {
1989
reclen, ok := direntReclen(buf)
1993
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true