1
2
3
4
5
6
7
8
9
10
11
12
13
14 package unix
15
16 import (
17 "bytes"
18 "fmt"
19 "os"
20 "reflect"
21 "regexp"
22 "runtime"
23 "sort"
24 "strings"
25 "sync"
26 "syscall"
27 "unsafe"
28 )
29
30
31 func initZosLibVec()
32
33
34 func GetZosLibVec() uintptr
35
36 func init() {
37 initZosLibVec()
38 r0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte("__ZOS_XSYSTRACE\x00"))[0])))
39 if r0 != 0 {
40 n, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)
41 ZosTraceLevel = int(n)
42 r0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte("__ZOS_XSYSTRACEFD\x00"))[0])))
43 if r0 != 0 {
44 fd, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)
45 f := os.NewFile(fd, "zostracefile")
46 if f != nil {
47 ZosTracefile = f
48 }
49 }
50
51 }
52 }
53
54
55 func CallLeFuncWithErr(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)
56
57
58 func CallLeFuncWithPtrReturn(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)
59
60
61
62
63
64
65
66 func ptrtest(uintptr) uint64
67
68
69
70
71 func safeload(ptr uintptr) (value uintptr, error uintptr)
72
73 const (
74 entrypointLocationOffset = 8
75
76 xplinkEyecatcher = 0x00c300c500c500f1
77 eyecatcherOffset = 16
78 ppa1LocationOffset = 8
79
80 nameLenOffset = 0x14
81 nameOffset = 0x16
82 )
83
84 func getPpaOffset(funcptr uintptr) int64 {
85 entrypoint, err := safeload(funcptr + entrypointLocationOffset)
86 if err != 0 {
87 return -1
88 }
89
90
91 val, err := safeload(entrypoint - eyecatcherOffset)
92 if err != 0 {
93 return -1
94 }
95 if val != xplinkEyecatcher {
96 return -1
97 }
98
99 ppaoff, err := safeload(entrypoint - ppa1LocationOffset)
100 if err != 0 {
101 return -1
102 }
103
104 ppaoff >>= 32
105 return int64(ppaoff)
106 }
107
108
109
110
111
112
113
114
115 func funcptrtest(funcptr uintptr, funcName string) uint64 {
116 entrypoint, err := safeload(funcptr + entrypointLocationOffset)
117 if err != 0 {
118 return 1
119 }
120
121 ppaoff := getPpaOffset(funcptr)
122 if ppaoff == -1 {
123 return 1
124 }
125
126
127 ppa1 := (entrypoint - eyecatcherOffset) + uintptr(ppaoff)
128
129 nameLen, err := safeload(ppa1 + nameLenOffset)
130 if err != 0 {
131 return 1
132 }
133
134 nameLen >>= 48
135 if nameLen > 128 {
136 return 1
137 }
138
139
140 if funcName == "" {
141 return 0
142 }
143
144 var funcname [128]byte
145 for i := 0; i < int(nameLen); i += 8 {
146 v, err := safeload(ppa1 + nameOffset + uintptr(i))
147 if err != 0 {
148 return 1
149 }
150 funcname[i] = byte(v >> 56)
151 funcname[i+1] = byte(v >> 48)
152 funcname[i+2] = byte(v >> 40)
153 funcname[i+3] = byte(v >> 32)
154 funcname[i+4] = byte(v >> 24)
155 funcname[i+5] = byte(v >> 16)
156 funcname[i+6] = byte(v >> 8)
157 funcname[i+7] = byte(v)
158 }
159
160 runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
161 []uintptr{uintptr(unsafe.Pointer(&funcname[0])), nameLen})
162
163 name := string(funcname[:nameLen])
164 if name != funcName {
165 return 1
166 }
167
168 return 0
169 }
170
171
172
173 func isValidLeFunc(f uintptr) error {
174 ret := funcptrtest(f, "")
175 if ret != 0 {
176 return fmt.Errorf("Bad pointer, not an LE function ")
177 }
178 return nil
179 }
180
181
182 func getLeFuncName(f uintptr) (string, error) {
183
184 entry := ((*[2]uintptr)(unsafe.Pointer(f)))[1]
185 preamp := ((*[4]uint32)(unsafe.Pointer(entry - eyecatcherOffset)))
186
187 offsetPpa1 := preamp[2]
188 if offsetPpa1 > 0x0ffff {
189 return "", fmt.Errorf("PPA1 offset seems too big 0x%x\n", offsetPpa1)
190 }
191
192 ppa1 := uintptr(unsafe.Pointer(preamp)) + uintptr(offsetPpa1)
193 res := ptrtest(ppa1)
194 if res != 0 {
195 return "", fmt.Errorf("PPA1 address not valid")
196 }
197
198 size := *(*uint16)(unsafe.Pointer(ppa1 + nameLenOffset))
199 if size > 128 {
200 return "", fmt.Errorf("Function name seems too long, length=%d\n", size)
201 }
202
203 var name [128]byte
204 funcname := (*[128]byte)(unsafe.Pointer(ppa1 + nameOffset))
205 copy(name[0:size], funcname[0:size])
206
207 runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
208 []uintptr{uintptr(unsafe.Pointer(&name[0])), uintptr(size)})
209
210 return string(name[:size]), nil
211 }
212
213
214 func zosLeVersion() (version, release uint32) {
215 p1 := (*(*uintptr)(unsafe.Pointer(uintptr(1208)))) >> 32
216 p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 88)))
217 p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 8)))
218 p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 984)))
219 vrm := *(*uint32)(unsafe.Pointer(p1 + 80))
220 version = (vrm & 0x00ff0000) >> 16
221 release = (vrm & 0x0000ff00) >> 8
222 return
223 }
224
225
226 func ZosStdioFilep(fd int32) uintptr {
227 return uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(uint64(*(*uint32)(unsafe.Pointer(uintptr(1208)))) + 80))) + uint64((fd+2)<<3))))))))
228 }
229
230 func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
231 stat.Dev = uint64(statLE.Dev)
232 stat.Ino = uint64(statLE.Ino)
233 stat.Nlink = uint64(statLE.Nlink)
234 stat.Mode = uint32(statLE.Mode)
235 stat.Uid = uint32(statLE.Uid)
236 stat.Gid = uint32(statLE.Gid)
237 stat.Rdev = uint64(statLE.Rdev)
238 stat.Size = statLE.Size
239 stat.Atim.Sec = int64(statLE.Atim)
240 stat.Atim.Nsec = 0
241 stat.Mtim.Sec = int64(statLE.Mtim)
242 stat.Mtim.Nsec = 0
243 stat.Ctim.Sec = int64(statLE.Ctim)
244 stat.Ctim.Nsec = 0
245 stat.Blksize = int64(statLE.Blksize)
246 stat.Blocks = statLE.Blocks
247 }
248
249 func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
250 func svcLoad(name *byte) unsafe.Pointer
251 func svcUnload(name *byte, fnptr unsafe.Pointer) int64
252
253 func (d *Dirent) NameString() string {
254 if d == nil {
255 return ""
256 }
257 s := string(d.Name[:])
258 idx := strings.IndexByte(s, 0)
259 if idx == -1 {
260 return s
261 } else {
262 return s[:idx]
263 }
264 }
265
266 func DecodeData(dest []byte, sz int, val uint64) {
267 for i := 0; i < sz; i++ {
268 dest[sz-1-i] = byte((val >> (uint64(i * 8))) & 0xff)
269 }
270 }
271
272 func EncodeData(data []byte) uint64 {
273 var value uint64
274 sz := len(data)
275 for i := 0; i < sz; i++ {
276 value |= uint64(data[i]) << uint64(((sz - i - 1) * 8))
277 }
278 return value
279 }
280
281 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
282 if sa.Port < 0 || sa.Port > 0xFFFF {
283 return nil, 0, EINVAL
284 }
285 sa.raw.Len = SizeofSockaddrInet4
286 sa.raw.Family = AF_INET
287 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
288 p[0] = byte(sa.Port >> 8)
289 p[1] = byte(sa.Port)
290 for i := 0; i < len(sa.Addr); i++ {
291 sa.raw.Addr[i] = sa.Addr[i]
292 }
293 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
294 }
295
296 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
297 if sa.Port < 0 || sa.Port > 0xFFFF {
298 return nil, 0, EINVAL
299 }
300 sa.raw.Len = SizeofSockaddrInet6
301 sa.raw.Family = AF_INET6
302 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
303 p[0] = byte(sa.Port >> 8)
304 p[1] = byte(sa.Port)
305 sa.raw.Scope_id = sa.ZoneId
306 for i := 0; i < len(sa.Addr); i++ {
307 sa.raw.Addr[i] = sa.Addr[i]
308 }
309 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
310 }
311
312 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
313 name := sa.Name
314 n := len(name)
315 if n >= len(sa.raw.Path) || n == 0 {
316 return nil, 0, EINVAL
317 }
318 sa.raw.Len = byte(3 + n)
319 sa.raw.Family = AF_UNIX
320 for i := 0; i < n; i++ {
321 sa.raw.Path[i] = int8(name[i])
322 }
323 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
324 }
325
326 func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
327
328 switch rsa.Addr.Family {
329 case AF_UNIX:
330 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
331 sa := new(SockaddrUnix)
332
333
334 if pp.Len != 0 && pp.Path[0] == 0 {
335
336
337
338
339
340 pp.Path[0] = '@'
341 }
342
343
344
345
346
347
348
349
350
351
352
353
354 n := 0
355 for n < int(pp.Len) && pp.Path[n] != 0 {
356 n++
357 }
358 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
359 return sa, nil
360
361 case AF_INET:
362 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
363 sa := new(SockaddrInet4)
364 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
365 sa.Port = int(p[0])<<8 + int(p[1])
366 for i := 0; i < len(sa.Addr); i++ {
367 sa.Addr[i] = pp.Addr[i]
368 }
369 return sa, nil
370
371 case AF_INET6:
372 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
373 sa := new(SockaddrInet6)
374 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
375 sa.Port = int(p[0])<<8 + int(p[1])
376 sa.ZoneId = pp.Scope_id
377 for i := 0; i < len(sa.Addr); i++ {
378 sa.Addr[i] = pp.Addr[i]
379 }
380 return sa, nil
381 }
382 return nil, EAFNOSUPPORT
383 }
384
385 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
386 var rsa RawSockaddrAny
387 var len _Socklen = SizeofSockaddrAny
388 nfd, err = accept(fd, &rsa, &len)
389 if err != nil {
390 return
391 }
392
393 sa, err = anyToSockaddr(0, &rsa)
394 if err != nil {
395 Close(nfd)
396 nfd = 0
397 }
398 return
399 }
400
401 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
402 var rsa RawSockaddrAny
403 var len _Socklen = SizeofSockaddrAny
404 nfd, err = accept4(fd, &rsa, &len, flags)
405 if err != nil {
406 return
407 }
408 if len > SizeofSockaddrAny {
409 panic("RawSockaddrAny too small")
410 }
411
412 sa, err = anyToSockaddr(0, &rsa)
413 if err != nil {
414 Close(nfd)
415 nfd = 0
416 }
417 return
418 }
419
420 func Ctermid() (tty string, err error) {
421 var termdev [1025]byte
422 runtime.EnterSyscall()
423 r0, err2, err1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___CTERMID_A<<4, uintptr(unsafe.Pointer(&termdev[0])))
424 runtime.ExitSyscall()
425 if r0 == 0 {
426 return "", fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
427 }
428 s := string(termdev[:])
429 idx := strings.Index(s, string(rune(0)))
430 if idx == -1 {
431 tty = s
432 } else {
433 tty = s[:idx]
434 }
435 return
436 }
437
438 func (iov *Iovec) SetLen(length int) {
439 iov.Len = uint64(length)
440 }
441
442 func (msghdr *Msghdr) SetControllen(length int) {
443 msghdr.Controllen = int32(length)
444 }
445
446 func (cmsg *Cmsghdr) SetLen(length int) {
447 cmsg.Len = int32(length)
448 }
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504 func Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
505 return Faccessat(dirfd, path, mode, flags)
506 }
507
508
509
510
511
512
513
514
515
516
517
518 func Fstat(fd int, stat *Stat_t) (err error) {
519 var statLE Stat_LE_t
520 err = fstat(fd, &statLE)
521 copyStat(stat, &statLE)
522 return
523 }
524
525 func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
526 var statLE Stat_LE_t
527 err = fstatat(dirfd, path, &statLE, flags)
528 copyStat(stat, &statLE)
529 return
530 }
531
532 func impl_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
533 var _p0 *byte
534 _p0, err = BytePtrFromString(path)
535 if err != nil {
536 return
537 }
538 var _p1 *byte
539 _p1, err = BytePtrFromString(attr)
540 if err != nil {
541 return
542 }
543 var _p2 unsafe.Pointer
544 if len(dest) > 0 {
545 _p2 = unsafe.Pointer(&dest[0])
546 } else {
547 _p2 = unsafe.Pointer(&_zero)
548 }
549 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___GETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)))
550 sz = int(r0)
551 if int64(r0) == -1 {
552 err = errnoErr2(e1, e2)
553 }
554 return
555 }
556
557
558 func get_GetxattrAddr() *(func(path string, attr string, dest []byte) (sz int, err error))
559
560 var Getxattr = enter_Getxattr
561
562 func enter_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
563 funcref := get_GetxattrAddr()
564 if validGetxattr() {
565 *funcref = impl_Getxattr
566 } else {
567 *funcref = error_Getxattr
568 }
569 return (*funcref)(path, attr, dest)
570 }
571
572 func error_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
573 return -1, ENOSYS
574 }
575
576 func validGetxattr() bool {
577 if funcptrtest(GetZosLibVec()+SYS___GETXATTR_A<<4, "") == 0 {
578 if name, err := getLeFuncName(GetZosLibVec() + SYS___GETXATTR_A<<4); err == nil {
579 return name == "__getxattr_a"
580 }
581 }
582 return false
583 }
584
585
586
587
588 func impl_Setxattr(path string, attr string, data []byte, flags int) (err error) {
589 var _p0 *byte
590 _p0, err = BytePtrFromString(path)
591 if err != nil {
592 return
593 }
594 var _p1 *byte
595 _p1, err = BytePtrFromString(attr)
596 if err != nil {
597 return
598 }
599 var _p2 unsafe.Pointer
600 if len(data) > 0 {
601 _p2 = unsafe.Pointer(&data[0])
602 } else {
603 _p2 = unsafe.Pointer(&_zero)
604 }
605 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags))
606 if int64(r0) == -1 {
607 err = errnoErr2(e1, e2)
608 }
609 return
610 }
611
612
613 func get_SetxattrAddr() *(func(path string, attr string, data []byte, flags int) (err error))
614
615 var Setxattr = enter_Setxattr
616
617 func enter_Setxattr(path string, attr string, data []byte, flags int) (err error) {
618 funcref := get_SetxattrAddr()
619 if validSetxattr() {
620 *funcref = impl_Setxattr
621 } else {
622 *funcref = error_Setxattr
623 }
624 return (*funcref)(path, attr, data, flags)
625 }
626
627 func error_Setxattr(path string, attr string, data []byte, flags int) (err error) {
628 return ENOSYS
629 }
630
631 func validSetxattr() bool {
632 if funcptrtest(GetZosLibVec()+SYS___SETXATTR_A<<4, "") == 0 {
633 if name, err := getLeFuncName(GetZosLibVec() + SYS___SETXATTR_A<<4); err == nil {
634 return name == "__setxattr_a"
635 }
636 }
637 return false
638 }
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662 func getPipe2Addr() *(func([]int, int) error)
663
664 var Pipe2 = pipe2Enter
665
666 func pipe2Enter(p []int, flags int) (err error) {
667 if funcptrtest(GetZosLibVec()+SYS_PIPE2<<4, "") == 0 {
668 *getPipe2Addr() = pipe2Impl
669 } else {
670 *getPipe2Addr() = pipe2Error
671 }
672 return (*getPipe2Addr())(p, flags)
673 }
674
675 func pipe2Impl(p []int, flags int) (err error) {
676 var pp [2]_C_int
677 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PIPE2<<4, uintptr(unsafe.Pointer(&pp[0])), uintptr(flags))
678 if int64(r0) == -1 {
679 err = errnoErr2(e1, e2)
680 } else {
681 p[0] = int(pp[0])
682 p[1] = int(pp[1])
683 }
684 return
685 }
686 func pipe2Error(p []int, flags int) (err error) {
687 return fmt.Errorf("Pipe2 is not available on this system")
688 }
689
690
691
692
693
694 func Readdir(dir uintptr) (dirent *Dirent, err error) {
695 runtime.EnterSyscall()
696 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READDIR_A<<4, uintptr(dir))
697 runtime.ExitSyscall()
698 dirent = (*Dirent)(unsafe.Pointer(r0))
699 if int64(r0) == -1 {
700 err = errnoErr2(e1, e2)
701 }
702 return
703 }
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719 func Ptsname(fd int) (name string, err error) {
720 runtime.EnterSyscall()
721 r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___PTSNAME_A<<4, uintptr(fd))
722 runtime.ExitSyscall()
723 if r0 == 0 {
724 err = errnoErr2(e1, e2)
725 } else {
726 name = u2s(unsafe.Pointer(r0))
727 }
728 return
729 }
730
731 func u2s(cstr unsafe.Pointer) string {
732 str := (*[1024]uint8)(cstr)
733 i := 0
734 for str[i] != 0 {
735 i++
736 }
737 return string(str[:i])
738 }
739
740 func Close(fd int) (err error) {
741 runtime.EnterSyscall()
742 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))
743 runtime.ExitSyscall()
744 for i := 0; e1 == EAGAIN && i < 10; i++ {
745 runtime.EnterSyscall()
746 CallLeFuncWithErr(GetZosLibVec()+SYS_USLEEP<<4, uintptr(10))
747 runtime.ExitSyscall()
748 runtime.EnterSyscall()
749 r0, e2, e1 = CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))
750 runtime.ExitSyscall()
751 }
752 if r0 != 0 {
753 err = errnoErr2(e1, e2)
754 }
755 return
756 }
757
758
759 func Madvise(b []byte, advice int) (err error) {
760 return
761 }
762
763 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
764 return mapper.Mmap(fd, offset, length, prot, flags)
765 }
766
767 func Munmap(b []byte) (err error) {
768 return mapper.Munmap(b)
769 }
770
771
772
773
774
775
776 func Getpgrp() (pid int) {
777 pid, _ = Getpgid(0)
778 return
779 }
780
781
782
783
784
785
786
787 func Getrusage(who int, rusage *Rusage) (err error) {
788 var ruz rusage_zos
789 err = getrusage(who, &ruz)
790
791 rusage.Utime.Sec = ruz.Utime.Sec
792 rusage.Utime.Usec = int64(ruz.Utime.Usec)
793 rusage.Stime.Sec = ruz.Stime.Sec
794 rusage.Stime.Usec = int64(ruz.Stime.Usec)
795 return
796 }
797
798
799
800
801
802
803
804
805
806
807
808
809 func Lstat(path string, stat *Stat_t) (err error) {
810 var statLE Stat_LE_t
811 err = lstat(path, &statLE)
812 copyStat(stat, &statLE)
813 return
814 }
815
816
817 func isSpecialPath(path []byte) (v bool) {
818 var special = [4][8]byte{
819 [8]byte{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},
820 [8]byte{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},
821 [8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},
822 [8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}
823
824 var i, j int
825 for i = 0; i < len(special); i++ {
826 for j = 0; j < len(special[i]); j++ {
827 if path[j] != special[i][j] {
828 break
829 }
830 }
831 if j == len(special[i]) {
832 return true
833 }
834 }
835 return false
836 }
837
838 func realpath(srcpath string, abspath []byte) (pathlen int, errno int) {
839 var source [1024]byte
840 copy(source[:], srcpath)
841 source[len(srcpath)] = 0
842 ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___REALPATH_A<<4,
843 []uintptr{uintptr(unsafe.Pointer(&source[0])),
844 uintptr(unsafe.Pointer(&abspath[0]))})
845 if ret != 0 {
846 index := bytes.IndexByte(abspath[:], byte(0))
847 if index != -1 {
848 return index, 0
849 }
850 } else {
851 errptr := (*int)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))
852 return 0, *errptr
853 }
854 return 0, 245
855 }
856
857 func Readlink(path string, buf []byte) (n int, err error) {
858 var _p0 *byte
859 _p0, err = BytePtrFromString(path)
860 if err != nil {
861 return
862 }
863 var _p1 unsafe.Pointer
864 if len(buf) > 0 {
865 _p1 = unsafe.Pointer(&buf[0])
866 } else {
867 _p1 = unsafe.Pointer(&_zero)
868 }
869 n = int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___READLINK_A<<4,
870 []uintptr{uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))}))
871 runtime.KeepAlive(unsafe.Pointer(_p0))
872 if n == -1 {
873 value := *(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))
874 err = errnoErr(Errno(value))
875 } else {
876 if buf[0] == '$' {
877 if isSpecialPath(buf[1:9]) {
878 cnt, err1 := realpath(path, buf)
879 if err1 == 0 {
880 n = cnt
881 }
882 }
883 }
884 }
885 return
886 }
887
888 func impl_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
889 var _p0 *byte
890 _p0, err = BytePtrFromString(path)
891 if err != nil {
892 return
893 }
894 var _p1 unsafe.Pointer
895 if len(buf) > 0 {
896 _p1 = unsafe.Pointer(&buf[0])
897 } else {
898 _p1 = unsafe.Pointer(&_zero)
899 }
900 runtime.EnterSyscall()
901 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READLINKAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
902 runtime.ExitSyscall()
903 n = int(r0)
904 if int64(r0) == -1 {
905 err = errnoErr2(e1, e2)
906 return n, err
907 } else {
908 if buf[0] == '$' {
909 if isSpecialPath(buf[1:9]) {
910 cnt, err1 := realpath(path, buf)
911 if err1 == 0 {
912 n = cnt
913 }
914 }
915 }
916 }
917 return
918 }
919
920
921 func get_ReadlinkatAddr() *(func(dirfd int, path string, buf []byte) (n int, err error))
922
923 var Readlinkat = enter_Readlinkat
924
925 func enter_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
926 funcref := get_ReadlinkatAddr()
927 if funcptrtest(GetZosLibVec()+SYS___READLINKAT_A<<4, "") == 0 {
928 *funcref = impl_Readlinkat
929 } else {
930 *funcref = error_Readlinkat
931 }
932 return (*funcref)(dirfd, path, buf)
933 }
934
935 func error_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
936 n = -1
937 err = ENOSYS
938 return
939 }
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971 func Stat(path string, sta *Stat_t) (err error) {
972 var statLE Stat_LE_t
973 err = stat(path, &statLE)
974 copyStat(sta, &statLE)
975 return
976 }
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991 func Open(path string, mode int, perm uint32) (fd int, err error) {
992 if mode&O_ACCMODE == 0 {
993 mode |= O_RDONLY
994 }
995 return open(path, mode, perm)
996 }
997
998
999
1000 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
1001 if flags&O_ACCMODE == 0 {
1002 flags |= O_RDONLY
1003 }
1004 return openat(dirfd, path, flags, mode)
1005 }
1006
1007
1008
1009 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
1010 if how.Flags&O_ACCMODE == 0 {
1011 how.Flags |= O_RDONLY
1012 }
1013 return openat2(dirfd, path, how, SizeofOpenHow)
1014 }
1015
1016 func ZosFdToPath(dirfd int) (path string, err error) {
1017 var buffer [1024]byte
1018 runtime.EnterSyscall()
1019 ret, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_W_IOCTL<<4, uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0])))
1020 runtime.ExitSyscall()
1021 if ret == 0 {
1022 zb := bytes.IndexByte(buffer[:], 0)
1023 if zb == -1 {
1024 zb = len(buffer)
1025 }
1026 CallLeFuncWithErr(GetZosLibVec()+SYS___E2A_L<<4, uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb))
1027 return string(buffer[:zb]), nil
1028 }
1029 return "", errnoErr2(e1, e2)
1030 }
1031
1032
1033
1034 func Remove(path string) error {
1035 return remove(path)
1036 }
1037
1038 const ImplementsGetwd = true
1039
1040 func Getcwd(buf []byte) (n int, err error) {
1041 var p unsafe.Pointer
1042 if len(buf) > 0 {
1043 p = unsafe.Pointer(&buf[0])
1044 } else {
1045 p = unsafe.Pointer(&_zero)
1046 }
1047 runtime.EnterSyscall()
1048 r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___GETCWD_A<<4, uintptr(p), uintptr(len(buf)))
1049 runtime.ExitSyscall()
1050 n = clen(buf) + 1
1051 if r0 == 0 {
1052 err = errnoErr2(e1, e2)
1053 }
1054 return
1055 }
1056
1057 func Getwd() (wd string, err error) {
1058 var buf [PathMax]byte
1059 n, err := Getcwd(buf[0:])
1060 if err != nil {
1061 return "", err
1062 }
1063
1064 if n < 1 || n > len(buf) || buf[n-1] != 0 {
1065 return "", EINVAL
1066 }
1067 return string(buf[0 : n-1]), nil
1068 }
1069
1070 func Getgroups() (gids []int, err error) {
1071 n, err := getgroups(0, nil)
1072 if err != nil {
1073 return nil, err
1074 }
1075 if n == 0 {
1076 return nil, nil
1077 }
1078
1079
1080 if n < 0 || n > 1<<20 {
1081 return nil, EINVAL
1082 }
1083
1084 a := make([]_Gid_t, n)
1085 n, err = getgroups(n, &a[0])
1086 if err != nil {
1087 return nil, err
1088 }
1089 gids = make([]int, n)
1090 for i, v := range a[0:n] {
1091 gids[i] = int(v)
1092 }
1093 return
1094 }
1095
1096 func Setgroups(gids []int) (err error) {
1097 if len(gids) == 0 {
1098 return setgroups(0, nil)
1099 }
1100
1101 a := make([]_Gid_t, len(gids))
1102 for i, v := range gids {
1103 a[i] = _Gid_t(v)
1104 }
1105 return setgroups(len(a), &a[0])
1106 }
1107
1108 func gettid() uint64
1109
1110 func Gettid() (tid int) {
1111 return int(gettid())
1112 }
1113
1114 type WaitStatus uint32
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125 const (
1126 mask = 0x7F
1127 core = 0x80
1128 exited = 0x00
1129 stopped = 0x7F
1130 shift = 8
1131 )
1132
1133 func (w WaitStatus) Exited() bool { return w&mask == exited }
1134
1135 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
1136
1137 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
1138
1139 func (w WaitStatus) Continued() bool { return w == 0xFFFF }
1140
1141 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
1142
1143 func (w WaitStatus) ExitStatus() int {
1144 if !w.Exited() {
1145 return -1
1146 }
1147 return int(w>>shift) & 0xFF
1148 }
1149
1150 func (w WaitStatus) Signal() Signal {
1151 if !w.Signaled() {
1152 return -1
1153 }
1154 return Signal(w & mask)
1155 }
1156
1157 func (w WaitStatus) StopSignal() Signal {
1158 if !w.Stopped() {
1159 return -1
1160 }
1161 return Signal(w>>shift) & 0xFF
1162 }
1163
1164 func (w WaitStatus) TrapCause() int { return -1 }
1165
1166
1167
1168 func Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) {
1169 return waitid(idType, id, info, options)
1170 }
1171
1172
1173
1174 func impl_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1175 runtime.EnterSyscall()
1176 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAIT4<<4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)))
1177 runtime.ExitSyscall()
1178 wpid = int(r0)
1179 if int64(r0) == -1 {
1180 err = errnoErr2(e1, e2)
1181 }
1182 return
1183 }
1184
1185
1186 func get_Wait4Addr() *(func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error))
1187
1188 var Wait4 = enter_Wait4
1189
1190 func enter_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1191 funcref := get_Wait4Addr()
1192 if funcptrtest(GetZosLibVec()+SYS_WAIT4<<4, "") == 0 {
1193 *funcref = impl_Wait4
1194 } else {
1195 *funcref = legacyWait4
1196 }
1197 return (*funcref)(pid, wstatus, options, rusage)
1198 }
1199
1200 func legacyWait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1201
1202
1203 var status _C_int
1204 wpid, err = waitpid(pid, &status, options)
1205 if wstatus != nil {
1206 *wstatus = WaitStatus(status)
1207 }
1208 return
1209 }
1210
1211
1212
1213 func Gettimeofday(tv *Timeval) (err error) {
1214 var tvz timeval_zos
1215 err = gettimeofday(&tvz)
1216 tv.Sec = tvz.Sec
1217 tv.Usec = int64(tvz.Usec)
1218 return
1219 }
1220
1221 func Time(t *Time_t) (tt Time_t, err error) {
1222 var tv Timeval
1223 err = Gettimeofday(&tv)
1224 if err != nil {
1225 return 0, err
1226 }
1227 if t != nil {
1228 *t = Time_t(tv.Sec)
1229 }
1230 return Time_t(tv.Sec), nil
1231 }
1232
1233 func setTimespec(sec, nsec int64) Timespec {
1234 return Timespec{Sec: sec, Nsec: nsec}
1235 }
1236
1237 func setTimeval(sec, usec int64) Timeval {
1238 return Timeval{Sec: sec, Usec: usec}
1239 }
1240
1241
1242
1243 func Pipe(p []int) (err error) {
1244 if len(p) != 2 {
1245 return EINVAL
1246 }
1247 var pp [2]_C_int
1248 err = pipe(&pp)
1249 p[0] = int(pp[0])
1250 p[1] = int(pp[1])
1251 return
1252 }
1253
1254
1255
1256 func Utimes(path string, tv []Timeval) (err error) {
1257 if tv == nil {
1258 return utimes(path, nil)
1259 }
1260 if len(tv) != 2 {
1261 return EINVAL
1262 }
1263 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
1264 }
1265
1266
1267
1268 func validUtimensat() bool {
1269 if funcptrtest(GetZosLibVec()+SYS___UTIMENSAT_A<<4, "") == 0 {
1270 if name, err := getLeFuncName(GetZosLibVec() + SYS___UTIMENSAT_A<<4); err == nil {
1271 return name == "__utimensat_a"
1272 }
1273 }
1274 return false
1275 }
1276
1277
1278
1279
1280 func get_UtimesNanoAddr() *(func(path string, ts []Timespec) (err error))
1281
1282 var UtimesNano = enter_UtimesNano
1283
1284 func enter_UtimesNano(path string, ts []Timespec) (err error) {
1285 funcref := get_UtimesNanoAddr()
1286 if validUtimensat() {
1287 *funcref = utimesNanoImpl
1288 } else {
1289 *funcref = legacyUtimesNano
1290 }
1291 return (*funcref)(path, ts)
1292 }
1293
1294 func utimesNanoImpl(path string, ts []Timespec) (err error) {
1295 if ts == nil {
1296 return utimensat(AT_FDCWD, path, nil, 0)
1297 }
1298 if len(ts) != 2 {
1299 return EINVAL
1300 }
1301 return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
1302 }
1303
1304 func legacyUtimesNano(path string, ts []Timespec) (err error) {
1305 if len(ts) != 2 {
1306 return EINVAL
1307 }
1308
1309
1310 tv := [2]Timeval{
1311 NsecToTimeval(TimespecToNsec(ts[0])),
1312 NsecToTimeval(TimespecToNsec(ts[1])),
1313 }
1314 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
1315 }
1316
1317
1318
1319
1320
1321
1322 func get_UtimesNanoAtAddr() *(func(dirfd int, path string, ts []Timespec, flags int) (err error))
1323
1324 var UtimesNanoAt = enter_UtimesNanoAt
1325
1326 func enter_UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
1327 funcref := get_UtimesNanoAtAddr()
1328 if validUtimensat() {
1329 *funcref = utimesNanoAtImpl
1330 } else {
1331 *funcref = legacyUtimesNanoAt
1332 }
1333 return (*funcref)(dirfd, path, ts, flags)
1334 }
1335
1336 func utimesNanoAtImpl(dirfd int, path string, ts []Timespec, flags int) (err error) {
1337 if ts == nil {
1338 return utimensat(dirfd, path, nil, flags)
1339 }
1340 if len(ts) != 2 {
1341 return EINVAL
1342 }
1343 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
1344 }
1345
1346 func legacyUtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
1347 if path[0] != '/' {
1348 dirPath, err := ZosFdToPath(dirfd)
1349 if err != nil {
1350 return err
1351 }
1352 path = dirPath + "/" + path
1353 }
1354 if flags == AT_SYMLINK_NOFOLLOW {
1355 if len(ts) != 2 {
1356 return EINVAL
1357 }
1358
1359 if ts[0].Nsec >= 5e8 {
1360 ts[0].Sec++
1361 }
1362 ts[0].Nsec = 0
1363 if ts[1].Nsec >= 5e8 {
1364 ts[1].Sec++
1365 }
1366 ts[1].Nsec = 0
1367
1368
1369
1370 tv := []Timeval{
1371 NsecToTimeval(TimespecToNsec(ts[0])),
1372 NsecToTimeval(TimespecToNsec(ts[1])),
1373 }
1374 return Lutimes(path, tv)
1375 }
1376 return UtimesNano(path, ts)
1377 }
1378
1379
1380
1381 func Getsockname(fd int) (sa Sockaddr, err error) {
1382 var rsa RawSockaddrAny
1383 var len _Socklen = SizeofSockaddrAny
1384 if err = getsockname(fd, &rsa, &len); err != nil {
1385 return
1386 }
1387
1388 return anyToSockaddr(0, &rsa)
1389 }
1390
1391 const (
1392
1393 nwmHeaderIdentifier = 0xd5e6d4c8
1394 nwmFilterIdentifier = 0xd5e6d4c6
1395 nwmTCPConnIdentifier = 0xd5e6d4c3
1396 nwmRecHeaderIdentifier = 0xd5e6d4d9
1397 nwmIPStatsIdentifier = 0xd5e6d4c9d7e2e340
1398 nwmIPGStatsIdentifier = 0xd5e6d4c9d7c7e2e3
1399 nwmTCPStatsIdentifier = 0xd5e6d4e3c3d7e2e3
1400 nwmUDPStatsIdentifier = 0xd5e6d4e4c4d7e2e3
1401 nwmICMPGStatsEntry = 0xd5e6d4c9c3d4d7c7
1402 nwmICMPTStatsEntry = 0xd5e6d4c9c3d4d7e3
1403
1404
1405 nwmVersion1 = 1
1406 nwmVersion2 = 2
1407 nwmCurrentVer = 2
1408
1409 nwmTCPConnType = 1
1410 nwmGlobalStatsType = 14
1411
1412
1413 nwmFilterLclAddrMask = 0x20000000
1414 nwmFilterSrcAddrMask = 0x20000000
1415 nwmFilterLclPortMask = 0x10000000
1416 nwmFilterSrcPortMask = 0x10000000
1417
1418
1419 nwmTCPStateClosed = 1
1420 nwmTCPStateListen = 2
1421 nwmTCPStateSynSent = 3
1422 nwmTCPStateSynRcvd = 4
1423 nwmTCPStateEstab = 5
1424 nwmTCPStateFinWait1 = 6
1425 nwmTCPStateFinWait2 = 7
1426 nwmTCPStateClosWait = 8
1427 nwmTCPStateLastAck = 9
1428 nwmTCPStateClosing = 10
1429 nwmTCPStateTimeWait = 11
1430 nwmTCPStateDeletTCB = 12
1431
1432
1433 BPF_TCP_CLOSE = 1
1434 BPF_TCP_LISTEN = 2
1435 BPF_TCP_SYN_SENT = 3
1436 BPF_TCP_SYN_RECV = 4
1437 BPF_TCP_ESTABLISHED = 5
1438 BPF_TCP_FIN_WAIT1 = 6
1439 BPF_TCP_FIN_WAIT2 = 7
1440 BPF_TCP_CLOSE_WAIT = 8
1441 BPF_TCP_LAST_ACK = 9
1442 BPF_TCP_CLOSING = 10
1443 BPF_TCP_TIME_WAIT = 11
1444 BPF_TCP_NEW_SYN_RECV = -1
1445 BPF_TCP_MAX_STATES = -2
1446 )
1447
1448 type nwmTriplet struct {
1449 offset uint32
1450 length uint32
1451 number uint32
1452 }
1453
1454 type nwmQuadruplet struct {
1455 offset uint32
1456 length uint32
1457 number uint32
1458 match uint32
1459 }
1460
1461 type nwmHeader struct {
1462 ident uint32
1463 length uint32
1464 version uint16
1465 nwmType uint16
1466 bytesNeeded uint32
1467 options uint32
1468 _ [16]byte
1469 inputDesc nwmTriplet
1470 outputDesc nwmQuadruplet
1471 }
1472
1473 type nwmFilter struct {
1474 ident uint32
1475 flags uint32
1476 resourceName [8]byte
1477 resourceId uint32
1478 listenerId uint32
1479 local [28]byte
1480 remote [28]byte
1481 _ uint16
1482 _ uint16
1483 asid uint16
1484 _ [2]byte
1485 tnLuName [8]byte
1486 tnMonGrp uint32
1487 tnAppl [8]byte
1488 applData [40]byte
1489 nInterface [16]byte
1490 dVipa [16]byte
1491 dVipaPfx uint16
1492 dVipaPort uint16
1493 dVipaFamily byte
1494 _ [3]byte
1495 destXCF [16]byte
1496 destXCFPfx uint16
1497 destXCFFamily byte
1498 _ [1]byte
1499 targIP [16]byte
1500 targIPPfx uint16
1501 targIPFamily byte
1502 _ [1]byte
1503 _ [20]byte
1504 }
1505
1506 type nwmRecHeader struct {
1507 ident uint32
1508 length uint32
1509 number byte
1510 _ [3]byte
1511 }
1512
1513 type nwmTCPStatsEntry struct {
1514 ident uint64
1515 currEstab uint32
1516 activeOpened uint32
1517 passiveOpened uint32
1518 connClosed uint32
1519 estabResets uint32
1520 attemptFails uint32
1521 passiveDrops uint32
1522 timeWaitReused uint32
1523 inSegs uint64
1524 predictAck uint32
1525 predictData uint32
1526 inDupAck uint32
1527 inBadSum uint32
1528 inBadLen uint32
1529 inShort uint32
1530 inDiscOldTime uint32
1531 inAllBeforeWin uint32
1532 inSomeBeforeWin uint32
1533 inAllAfterWin uint32
1534 inSomeAfterWin uint32
1535 inOutOfOrder uint32
1536 inAfterClose uint32
1537 inWinProbes uint32
1538 inWinUpdates uint32
1539 outWinUpdates uint32
1540 outSegs uint64
1541 outDelayAcks uint32
1542 outRsts uint32
1543 retransSegs uint32
1544 retransTimeouts uint32
1545 retransDrops uint32
1546 pmtuRetrans uint32
1547 pmtuErrors uint32
1548 outWinProbes uint32
1549 probeDrops uint32
1550 keepAliveProbes uint32
1551 keepAliveDrops uint32
1552 finwait2Drops uint32
1553 acceptCount uint64
1554 inBulkQSegs uint64
1555 inDiscards uint64
1556 connFloods uint32
1557 connStalls uint32
1558 cfgEphemDef uint16
1559 ephemInUse uint16
1560 ephemHiWater uint16
1561 flags byte
1562 _ [1]byte
1563 ephemExhaust uint32
1564 smcRCurrEstabLnks uint32
1565 smcRLnkActTimeOut uint32
1566 smcRActLnkOpened uint32
1567 smcRPasLnkOpened uint32
1568 smcRLnksClosed uint32
1569 smcRCurrEstab uint32
1570 smcRActiveOpened uint32
1571 smcRPassiveOpened uint32
1572 smcRConnClosed uint32
1573 smcRInSegs uint64
1574 smcROutSegs uint64
1575 smcRInRsts uint32
1576 smcROutRsts uint32
1577 smcDCurrEstabLnks uint32
1578 smcDActLnkOpened uint32
1579 smcDPasLnkOpened uint32
1580 smcDLnksClosed uint32
1581 smcDCurrEstab uint32
1582 smcDActiveOpened uint32
1583 smcDPassiveOpened uint32
1584 smcDConnClosed uint32
1585 smcDInSegs uint64
1586 smcDOutSegs uint64
1587 smcDInRsts uint32
1588 smcDOutRsts uint32
1589 }
1590
1591 type nwmConnEntry struct {
1592 ident uint32
1593 local [28]byte
1594 remote [28]byte
1595 startTime [8]byte
1596 lastActivity [8]byte
1597 bytesIn [8]byte
1598 bytesOut [8]byte
1599 inSegs [8]byte
1600 outSegs [8]byte
1601 state uint16
1602 activeOpen byte
1603 flag01 byte
1604 outBuffered uint32
1605 inBuffered uint32
1606 maxSndWnd uint32
1607 reXmtCount uint32
1608 congestionWnd uint32
1609 ssThresh uint32
1610 roundTripTime uint32
1611 roundTripVar uint32
1612 sendMSS uint32
1613 sndWnd uint32
1614 rcvBufSize uint32
1615 sndBufSize uint32
1616 outOfOrderCount uint32
1617 lcl0WindowCount uint32
1618 rmt0WindowCount uint32
1619 dupacks uint32
1620 flag02 byte
1621 sockOpt6Cont byte
1622 asid uint16
1623 resourceName [8]byte
1624 resourceId uint32
1625 subtask uint32
1626 sockOpt byte
1627 sockOpt6 byte
1628 clusterConnFlag byte
1629 proto byte
1630 targetAppl [8]byte
1631 luName [8]byte
1632 clientUserId [8]byte
1633 logMode [8]byte
1634 timeStamp uint32
1635 timeStampAge uint32
1636 serverResourceId uint32
1637 intfName [16]byte
1638 ttlsStatPol byte
1639 ttlsStatConn byte
1640 ttlsSSLProt uint16
1641 ttlsNegCiph [2]byte
1642 ttlsSecType byte
1643 ttlsFIPS140Mode byte
1644 ttlsUserID [8]byte
1645 applData [40]byte
1646 inOldestTime [8]byte
1647 outOldestTime [8]byte
1648 tcpTrustedPartner byte
1649 _ [3]byte
1650 bulkDataIntfName [16]byte
1651 ttlsNegCiph4 [4]byte
1652 smcReason uint32
1653 lclSMCLinkId uint32
1654 rmtSMCLinkId uint32
1655 smcStatus byte
1656 smcFlags byte
1657 _ [2]byte
1658 rcvWnd uint32
1659 lclSMCBufSz uint32
1660 rmtSMCBufSz uint32
1661 ttlsSessID [32]byte
1662 ttlsSessIDLen int16
1663 _ [1]byte
1664 smcDStatus byte
1665 smcDReason uint32
1666 }
1667
1668 var svcNameTable [][]byte = [][]byte{
1669 []byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"),
1670 }
1671
1672 const (
1673 svc_EZBNMIF4 = 0
1674 )
1675
1676 func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
1677 jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40")
1678 responseBuffer := [4096]byte{0}
1679 var bufferAlet, reasonCode uint32 = 0, 0
1680 var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
1681
1682 dsa := [18]uint64{0}
1683 var argv [7]unsafe.Pointer
1684 argv[0] = unsafe.Pointer(&jobname[0])
1685 argv[1] = unsafe.Pointer(&responseBuffer[0])
1686 argv[2] = unsafe.Pointer(&bufferAlet)
1687 argv[3] = unsafe.Pointer(&bufferLen)
1688 argv[4] = unsafe.Pointer(&returnValue)
1689 argv[5] = unsafe.Pointer(&returnCode)
1690 argv[6] = unsafe.Pointer(&reasonCode)
1691
1692 request := (*struct {
1693 header nwmHeader
1694 filter nwmFilter
1695 })(unsafe.Pointer(&responseBuffer[0]))
1696
1697 EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
1698 if EZBNMIF4 == nil {
1699 return nil, errnoErr(EINVAL)
1700 }
1701
1702
1703 request.header.ident = nwmHeaderIdentifier
1704 request.header.length = uint32(unsafe.Sizeof(request.header))
1705 request.header.version = nwmCurrentVer
1706 request.header.nwmType = nwmGlobalStatsType
1707 request.header.options = 0x80000000
1708
1709 svcCall(EZBNMIF4, &argv[0], &dsa[0])
1710
1711
1712 if returnCode != 0 || request.header.outputDesc.offset == 0 {
1713 return nil, errnoErr(EINVAL)
1714 }
1715
1716
1717 recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
1718 if recHeader.ident != nwmRecHeaderIdentifier {
1719 return nil, errnoErr(EINVAL)
1720 }
1721
1722
1723 var sections []*uint64
1724 var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
1725 for i := uint32(0); i < uint32(recHeader.number); i++ {
1726 offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
1727 sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
1728 for j := uint32(0); j < sectionDesc.number; j++ {
1729 offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
1730 sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
1731 }
1732 }
1733
1734
1735 var tcpStats *nwmTCPStatsEntry = nil
1736 for _, ptr := range sections {
1737 switch *ptr {
1738 case nwmTCPStatsIdentifier:
1739 if tcpStats != nil {
1740 return nil, errnoErr(EINVAL)
1741 }
1742 tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
1743 case nwmIPStatsIdentifier:
1744 case nwmIPGStatsIdentifier:
1745 case nwmUDPStatsIdentifier:
1746 case nwmICMPGStatsEntry:
1747 case nwmICMPTStatsEntry:
1748 default:
1749 return nil, errnoErr(EINVAL)
1750 }
1751 }
1752 if tcpStats == nil {
1753 return nil, errnoErr(EINVAL)
1754 }
1755
1756
1757 responseBuffer = [4096]byte{0}
1758 dsa = [18]uint64{0}
1759 bufferAlet, reasonCode = 0, 0
1760 bufferLen, returnValue, returnCode = 4096, 0, 0
1761 nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c)))
1762 nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
1763 argv[0] = unsafe.Pointer(uintptr(*nameptr))
1764
1765 request.header.ident = nwmHeaderIdentifier
1766 request.header.length = uint32(unsafe.Sizeof(request.header))
1767 request.header.version = nwmCurrentVer
1768 request.header.nwmType = nwmTCPConnType
1769 request.header.options = 0x80000000
1770
1771 request.filter.ident = nwmFilterIdentifier
1772
1773 var localSockaddr RawSockaddrAny
1774 socklen := _Socklen(SizeofSockaddrAny)
1775 err := getsockname(fd, &localSockaddr, &socklen)
1776 if err != nil {
1777 return nil, errnoErr(EINVAL)
1778 }
1779 if localSockaddr.Addr.Family == AF_INET {
1780 localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
1781 localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
1782 localSockFilter.Family = AF_INET
1783 var i int
1784 for i = 0; i < 4; i++ {
1785 if localSockaddr.Addr[i] != 0 {
1786 break
1787 }
1788 }
1789 if i != 4 {
1790 request.filter.flags |= nwmFilterLclAddrMask
1791 for i = 0; i < 4; i++ {
1792 localSockFilter.Addr[i] = localSockaddr.Addr[i]
1793 }
1794 }
1795 if localSockaddr.Port != 0 {
1796 request.filter.flags |= nwmFilterLclPortMask
1797 localSockFilter.Port = localSockaddr.Port
1798 }
1799 } else if localSockaddr.Addr.Family == AF_INET6 {
1800 localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
1801 localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
1802 localSockFilter.Family = AF_INET6
1803 var i int
1804 for i = 0; i < 16; i++ {
1805 if localSockaddr.Addr[i] != 0 {
1806 break
1807 }
1808 }
1809 if i != 16 {
1810 request.filter.flags |= nwmFilterLclAddrMask
1811 for i = 0; i < 16; i++ {
1812 localSockFilter.Addr[i] = localSockaddr.Addr[i]
1813 }
1814 }
1815 if localSockaddr.Port != 0 {
1816 request.filter.flags |= nwmFilterLclPortMask
1817 localSockFilter.Port = localSockaddr.Port
1818 }
1819 }
1820
1821 svcCall(EZBNMIF4, &argv[0], &dsa[0])
1822
1823
1824 if returnCode != 0 || request.header.outputDesc.offset == 0 {
1825 return nil, errnoErr(EINVAL)
1826 }
1827
1828
1829 conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
1830 if conn.ident != nwmTCPConnIdentifier {
1831 return nil, errnoErr(EINVAL)
1832 }
1833
1834
1835
1836
1837
1838 var tcpinfo TCPInfo
1839 tcpinfo.State = uint8(conn.state)
1840 tcpinfo.Ca_state = 0
1841 tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
1842 tcpinfo.Probes = uint8(tcpStats.outWinProbes)
1843 tcpinfo.Backoff = 0
1844 tcpinfo.Options = 0
1845 tcpinfo.Rto = tcpStats.retransTimeouts
1846 tcpinfo.Ato = tcpStats.outDelayAcks
1847 tcpinfo.Snd_mss = conn.sendMSS
1848 tcpinfo.Rcv_mss = conn.sendMSS
1849 tcpinfo.Unacked = 0
1850 tcpinfo.Sacked = 0
1851 tcpinfo.Lost = 0
1852 tcpinfo.Retrans = conn.reXmtCount
1853 tcpinfo.Fackets = 0
1854 tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
1855 tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
1856 tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
1857 tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
1858 tcpinfo.Pmtu = conn.sendMSS
1859 tcpinfo.Rcv_ssthresh = conn.ssThresh
1860 tcpinfo.Rtt = conn.roundTripTime
1861 tcpinfo.Rttvar = conn.roundTripVar
1862 tcpinfo.Snd_ssthresh = conn.ssThresh
1863 tcpinfo.Snd_cwnd = conn.congestionWnd
1864 tcpinfo.Advmss = conn.sendMSS
1865 tcpinfo.Reordering = 0
1866 tcpinfo.Rcv_rtt = conn.roundTripTime
1867 tcpinfo.Rcv_space = conn.sendMSS
1868 tcpinfo.Total_retrans = conn.reXmtCount
1869
1870 svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
1871
1872 return &tcpinfo, nil
1873 }
1874
1875
1876
1877 func GetsockoptString(fd, level, opt int) (string, error) {
1878 buf := make([]byte, 256)
1879 vallen := _Socklen(len(buf))
1880 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1881 if err != nil {
1882 return "", err
1883 }
1884
1885 return ByteSliceToString(buf[:vallen]), nil
1886 }
1887
1888 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
1889 var msg Msghdr
1890 var rsa RawSockaddrAny
1891 msg.Name = (*byte)(unsafe.Pointer(&rsa))
1892 msg.Namelen = SizeofSockaddrAny
1893 var iov Iovec
1894 if len(p) > 0 {
1895 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
1896 iov.SetLen(len(p))
1897 }
1898 var dummy byte
1899 if len(oob) > 0 {
1900
1901 if len(p) == 0 {
1902 iov.Base = &dummy
1903 iov.SetLen(1)
1904 }
1905 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
1906 msg.SetControllen(len(oob))
1907 }
1908 msg.Iov = &iov
1909 msg.Iovlen = 1
1910 if n, err = recvmsg(fd, &msg, flags); err != nil {
1911 return
1912 }
1913 oobn = int(msg.Controllen)
1914 recvflags = int(msg.Flags)
1915
1916 if rsa.Addr.Family != AF_UNSPEC {
1917
1918 from, err = anyToSockaddr(0, &rsa)
1919 }
1920 return
1921 }
1922
1923 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
1924 _, err = SendmsgN(fd, p, oob, to, flags)
1925 return
1926 }
1927
1928 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
1929 var ptr unsafe.Pointer
1930 var salen _Socklen
1931 if to != nil {
1932 var err error
1933 ptr, salen, err = to.sockaddr()
1934 if err != nil {
1935 return 0, err
1936 }
1937 }
1938 var msg Msghdr
1939 msg.Name = (*byte)(unsafe.Pointer(ptr))
1940 msg.Namelen = int32(salen)
1941 var iov Iovec
1942 if len(p) > 0 {
1943 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
1944 iov.SetLen(len(p))
1945 }
1946 var dummy byte
1947 if len(oob) > 0 {
1948
1949 if len(p) == 0 {
1950 iov.Base = &dummy
1951 iov.SetLen(1)
1952 }
1953 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
1954 msg.SetControllen(len(oob))
1955 }
1956 msg.Iov = &iov
1957 msg.Iovlen = 1
1958 if n, err = sendmsg(fd, &msg, flags); err != nil {
1959 return 0, err
1960 }
1961 if len(oob) > 0 && len(p) == 0 {
1962 n = 0
1963 }
1964 return n, nil
1965 }
1966
1967 func Opendir(name string) (uintptr, error) {
1968 p, err := BytePtrFromString(name)
1969 if err != nil {
1970 return 0, err
1971 }
1972 err = nil
1973 runtime.EnterSyscall()
1974 dir, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___OPENDIR_A<<4, uintptr(unsafe.Pointer(p)))
1975 runtime.ExitSyscall()
1976 runtime.KeepAlive(unsafe.Pointer(p))
1977 if dir == 0 {
1978 err = errnoErr2(e1, e2)
1979 }
1980 return dir, err
1981 }
1982
1983
1984 func clearErrno()
1985
1986 func Closedir(dir uintptr) error {
1987 runtime.EnterSyscall()
1988 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSEDIR<<4, dir)
1989 runtime.ExitSyscall()
1990 if r0 != 0 {
1991 return errnoErr2(e1, e2)
1992 }
1993 return nil
1994 }
1995
1996 func Seekdir(dir uintptr, pos int) {
1997 runtime.EnterSyscall()
1998 CallLeFuncWithErr(GetZosLibVec()+SYS_SEEKDIR<<4, dir, uintptr(pos))
1999 runtime.ExitSyscall()
2000 }
2001
2002 func Telldir(dir uintptr) (int, error) {
2003 p, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TELLDIR<<4, dir)
2004 pos := int(p)
2005 if int64(p) == -1 {
2006 return pos, errnoErr2(e1, e2)
2007 }
2008 return pos, nil
2009 }
2010
2011
2012 func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
2013
2014
2015 var flock [24]byte
2016 *(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
2017 *(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
2018 *(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
2019 *(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
2020 *(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
2021 runtime.EnterSyscall()
2022 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
2023 runtime.ExitSyscall()
2024 lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
2025 lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
2026 lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
2027 lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
2028 lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
2029 if r0 == 0 {
2030 return nil
2031 }
2032 return errnoErr2(e1, e2)
2033 }
2034
2035 func impl_Flock(fd int, how int) (err error) {
2036 runtime.EnterSyscall()
2037 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FLOCK<<4, uintptr(fd), uintptr(how))
2038 runtime.ExitSyscall()
2039 if int64(r0) == -1 {
2040 err = errnoErr2(e1, e2)
2041 }
2042 return
2043 }
2044
2045
2046 func get_FlockAddr() *(func(fd int, how int) (err error))
2047
2048 var Flock = enter_Flock
2049
2050 func validFlock(fp uintptr) bool {
2051 if funcptrtest(GetZosLibVec()+SYS_FLOCK<<4, "") == 0 {
2052 if name, err := getLeFuncName(GetZosLibVec() + SYS_FLOCK<<4); err == nil {
2053 return name == "flock"
2054 }
2055 }
2056 return false
2057 }
2058
2059 func enter_Flock(fd int, how int) (err error) {
2060 funcref := get_FlockAddr()
2061 if validFlock(GetZosLibVec() + SYS_FLOCK<<4) {
2062 *funcref = impl_Flock
2063 } else {
2064 *funcref = legacyFlock
2065 }
2066 return (*funcref)(fd, how)
2067 }
2068
2069 func legacyFlock(fd int, how int) error {
2070
2071 var flock_type int16
2072 var fcntl_cmd int
2073
2074 switch how {
2075 case LOCK_SH | LOCK_NB:
2076 flock_type = F_RDLCK
2077 fcntl_cmd = F_SETLK
2078 case LOCK_EX | LOCK_NB:
2079 flock_type = F_WRLCK
2080 fcntl_cmd = F_SETLK
2081 case LOCK_EX:
2082 flock_type = F_WRLCK
2083 fcntl_cmd = F_SETLKW
2084 case LOCK_UN:
2085 flock_type = F_UNLCK
2086 fcntl_cmd = F_SETLKW
2087 default:
2088 }
2089
2090 flock := Flock_t{
2091 Type: int16(flock_type),
2092 Whence: int16(0),
2093 Start: int64(0),
2094 Len: int64(0),
2095 Pid: int32(Getppid()),
2096 }
2097
2098 err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
2099 return err
2100 }
2101
2102 func Mlock(b []byte) (err error) {
2103 runtime.EnterSyscall()
2104 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2105 runtime.ExitSyscall()
2106 if r0 != 0 {
2107 err = errnoErr2(e1, e2)
2108 }
2109 return
2110 }
2111
2112 func Mlock2(b []byte, flags int) (err error) {
2113 runtime.EnterSyscall()
2114 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2115 runtime.ExitSyscall()
2116 if r0 != 0 {
2117 err = errnoErr2(e1, e2)
2118 }
2119 return
2120 }
2121
2122 func Mlockall(flags int) (err error) {
2123 runtime.EnterSyscall()
2124 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2125 runtime.ExitSyscall()
2126 if r0 != 0 {
2127 err = errnoErr2(e1, e2)
2128 }
2129 return
2130 }
2131
2132 func Munlock(b []byte) (err error) {
2133 runtime.EnterSyscall()
2134 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
2135 runtime.ExitSyscall()
2136 if r0 != 0 {
2137 err = errnoErr2(e1, e2)
2138 }
2139 return
2140 }
2141
2142 func Munlockall() (err error) {
2143 runtime.EnterSyscall()
2144 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
2145 runtime.ExitSyscall()
2146 if r0 != 0 {
2147 err = errnoErr2(e1, e2)
2148 }
2149 return
2150 }
2151
2152 func ClockGettime(clockid int32, ts *Timespec) error {
2153
2154 var ticks_per_sec uint32 = 100
2155 var nsec_per_sec int64 = 1000000000
2156
2157 if ts == nil {
2158 return EFAULT
2159 }
2160 if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
2161 var nanotime int64 = runtime.Nanotime1()
2162 ts.Sec = nanotime / nsec_per_sec
2163 ts.Nsec = nanotime % nsec_per_sec
2164 } else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
2165 var tm Tms
2166 _, err := Times(&tm)
2167 if err != nil {
2168 return EFAULT
2169 }
2170 ts.Sec = int64(tm.Utime / ticks_per_sec)
2171 ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
2172 } else {
2173 return EINVAL
2174 }
2175 return nil
2176 }
2177
2178
2179
2180
2181 func get_ChtagAddr() *(func(path string, ccsid uint64, textbit uint64) error)
2182
2183 var Chtag = enter_Chtag
2184
2185 func enter_Chtag(path string, ccsid uint64, textbit uint64) error {
2186 funcref := get_ChtagAddr()
2187 if validSetxattr() {
2188 *funcref = impl_Chtag
2189 } else {
2190 *funcref = legacy_Chtag
2191 }
2192 return (*funcref)(path, ccsid, textbit)
2193 }
2194
2195 func legacy_Chtag(path string, ccsid uint64, textbit uint64) error {
2196 tag := ccsid<<16 | textbit<<15
2197 var tag_buff [8]byte
2198 DecodeData(tag_buff[:], 8, tag)
2199 return Setxattr(path, "filetag", tag_buff[:], XATTR_REPLACE)
2200 }
2201
2202 func impl_Chtag(path string, ccsid uint64, textbit uint64) error {
2203 tag := ccsid<<16 | textbit<<15
2204 var tag_buff [4]byte
2205 DecodeData(tag_buff[:], 4, tag)
2206 return Setxattr(path, "system.filetag", tag_buff[:], XATTR_REPLACE)
2207 }
2208
2209
2210
2211
2212
2213
2214 func get_NanosleepAddr() *(func(time *Timespec, leftover *Timespec) error)
2215
2216 var Nanosleep = enter_Nanosleep
2217
2218 func enter_Nanosleep(time *Timespec, leftover *Timespec) error {
2219 funcref := get_NanosleepAddr()
2220 if funcptrtest(GetZosLibVec()+SYS_NANOSLEEP<<4, "") == 0 {
2221 *funcref = impl_Nanosleep
2222 } else {
2223 *funcref = legacyNanosleep
2224 }
2225 return (*funcref)(time, leftover)
2226 }
2227
2228 func impl_Nanosleep(time *Timespec, leftover *Timespec) error {
2229 runtime.EnterSyscall()
2230 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_NANOSLEEP<<4, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)))
2231 runtime.ExitSyscall()
2232 if int64(r0) == -1 {
2233 return errnoErr2(e1, e2)
2234 }
2235 return nil
2236 }
2237
2238 func legacyNanosleep(time *Timespec, leftover *Timespec) error {
2239 t0 := runtime.Nanotime1()
2240 var secrem uint32
2241 var nsecrem uint32
2242 total := time.Sec*1000000000 + time.Nsec
2243 elapsed := runtime.Nanotime1() - t0
2244 var rv int32
2245 var rc int32
2246 var err error
2247
2248 for total-elapsed > 1000000000 {
2249 rv, rc, _ = BpxCondTimedWait(uint32(1), uint32(0), uint32(CW_CONDVAR), &secrem, &nsecrem)
2250 if rv != 0 && rc != 112 {
2251 if leftover != nil && rc == 120 {
2252 leftover.Sec = int64(secrem)
2253 leftover.Nsec = int64(nsecrem)
2254 }
2255 err = Errno(rc)
2256 return err
2257 }
2258 elapsed = runtime.Nanotime1() - t0
2259 }
2260
2261 if total > elapsed {
2262 rv, rc, _ = BpxCondTimedWait(uint32(0), uint32(total-elapsed), uint32(CW_CONDVAR), &secrem, &nsecrem)
2263 }
2264 if leftover != nil && rc == 120 {
2265 leftover.Sec = int64(secrem)
2266 leftover.Nsec = int64(nsecrem)
2267 }
2268 if rv != 0 && rc != 112 {
2269 err = Errno(rc)
2270 }
2271 return err
2272 }
2273
2274
2275
2276 var (
2277 Stdin = 0
2278 Stdout = 1
2279 Stderr = 2
2280 )
2281
2282
2283
2284 var (
2285 errEAGAIN error = syscall.EAGAIN
2286 errEINVAL error = syscall.EINVAL
2287 errENOENT error = syscall.ENOENT
2288 )
2289
2290 var ZosTraceLevel int
2291 var ZosTracefile *os.File
2292
2293 var (
2294 signalNameMapOnce sync.Once
2295 signalNameMap map[string]syscall.Signal
2296 )
2297
2298
2299
2300 func errnoErr(e Errno) error {
2301 switch e {
2302 case 0:
2303 return nil
2304 case EAGAIN:
2305 return errEAGAIN
2306 case EINVAL:
2307 return errEINVAL
2308 case ENOENT:
2309 return errENOENT
2310 }
2311 return e
2312 }
2313
2314 var reg *regexp.Regexp
2315
2316
2317 func errnoErr2(e Errno, e2 uintptr) error {
2318 switch e {
2319 case 0:
2320 return nil
2321 case EAGAIN:
2322 return errEAGAIN
2323
2330 }
2331 if ZosTraceLevel > 0 {
2332 var name string
2333 if reg == nil {
2334 reg = regexp.MustCompile("(^unix\\.[^/]+$|.*\\/unix\\.[^/]+$)")
2335 }
2336 i := 1
2337 pc, file, line, ok := runtime.Caller(i)
2338 if ok {
2339 name = runtime.FuncForPC(pc).Name()
2340 }
2341 for ok && reg.MatchString(runtime.FuncForPC(pc).Name()) {
2342 i += 1
2343 pc, file, line, ok = runtime.Caller(i)
2344 }
2345 if ok {
2346 if ZosTracefile == nil {
2347 ZosConsolePrintf("From %s:%d\n", file, line)
2348 ZosConsolePrintf("%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
2349 } else {
2350 fmt.Fprintf(ZosTracefile, "From %s:%d\n", file, line)
2351 fmt.Fprintf(ZosTracefile, "%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
2352 }
2353 } else {
2354 if ZosTracefile == nil {
2355 ZosConsolePrintf("%s (errno2=0x%x)\n", e.Error(), e2)
2356 } else {
2357 fmt.Fprintf(ZosTracefile, "%s (errno2=0x%x)\n", e.Error(), e2)
2358 }
2359 }
2360 }
2361 return e
2362 }
2363
2364
2365 func ErrnoName(e Errno) string {
2366 i := sort.Search(len(errorList), func(i int) bool {
2367 return errorList[i].num >= e
2368 })
2369 if i < len(errorList) && errorList[i].num == e {
2370 return errorList[i].name
2371 }
2372 return ""
2373 }
2374
2375
2376 func SignalName(s syscall.Signal) string {
2377 i := sort.Search(len(signalList), func(i int) bool {
2378 return signalList[i].num >= s
2379 })
2380 if i < len(signalList) && signalList[i].num == s {
2381 return signalList[i].name
2382 }
2383 return ""
2384 }
2385
2386
2387
2388
2389 func SignalNum(s string) syscall.Signal {
2390 signalNameMapOnce.Do(func() {
2391 signalNameMap = make(map[string]syscall.Signal, len(signalList))
2392 for _, signal := range signalList {
2393 signalNameMap[signal.name] = signal.num
2394 }
2395 })
2396 return signalNameMap[s]
2397 }
2398
2399
2400 func clen(n []byte) int {
2401 i := bytes.IndexByte(n, 0)
2402 if i == -1 {
2403 i = len(n)
2404 }
2405 return i
2406 }
2407
2408
2409
2410 type mmapper struct {
2411 sync.Mutex
2412 active map[*byte][]byte
2413 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
2414 munmap func(addr uintptr, length uintptr) error
2415 }
2416
2417 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
2418 if length <= 0 {
2419 return nil, EINVAL
2420 }
2421
2422
2423 flags |= __MAP_64
2424
2425
2426 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
2427 if errno != nil {
2428 return nil, errno
2429 }
2430
2431
2432 var sl = struct {
2433 addr uintptr
2434 len int
2435 cap int
2436 }{addr, length, length}
2437
2438
2439 b := *(*[]byte)(unsafe.Pointer(&sl))
2440
2441
2442 p := &b[cap(b)-1]
2443 m.Lock()
2444 defer m.Unlock()
2445 m.active[p] = b
2446 return b, nil
2447 }
2448
2449 func (m *mmapper) Munmap(data []byte) (err error) {
2450 if len(data) == 0 || len(data) != cap(data) {
2451 return EINVAL
2452 }
2453
2454
2455 p := &data[cap(data)-1]
2456 m.Lock()
2457 defer m.Unlock()
2458 b := m.active[p]
2459 if b == nil || &b[0] != &data[0] {
2460 return EINVAL
2461 }
2462
2463
2464 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
2465 return errno
2466 }
2467 delete(m.active, p)
2468 return nil
2469 }
2470
2471 func Read(fd int, p []byte) (n int, err error) {
2472 n, err = read(fd, p)
2473 if raceenabled {
2474 if n > 0 {
2475 raceWriteRange(unsafe.Pointer(&p[0]), n)
2476 }
2477 if err == nil {
2478 raceAcquire(unsafe.Pointer(&ioSync))
2479 }
2480 }
2481 return
2482 }
2483
2484 func Write(fd int, p []byte) (n int, err error) {
2485 if raceenabled {
2486 raceReleaseMerge(unsafe.Pointer(&ioSync))
2487 }
2488 n, err = write(fd, p)
2489 if raceenabled && n > 0 {
2490 raceReadRange(unsafe.Pointer(&p[0]), n)
2491 }
2492 return
2493 }
2494
2495
2496
2497 var SocketDisableIPv6 bool
2498
2499
2500 type Sockaddr interface {
2501 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
2502 }
2503
2504
2505 type SockaddrInet4 struct {
2506 Port int
2507 Addr [4]byte
2508 raw RawSockaddrInet4
2509 }
2510
2511
2512 type SockaddrInet6 struct {
2513 Port int
2514 ZoneId uint32
2515 Addr [16]byte
2516 raw RawSockaddrInet6
2517 }
2518
2519
2520 type SockaddrUnix struct {
2521 Name string
2522 raw RawSockaddrUnix
2523 }
2524
2525 func Bind(fd int, sa Sockaddr) (err error) {
2526 ptr, n, err := sa.sockaddr()
2527 if err != nil {
2528 return err
2529 }
2530 return bind(fd, ptr, n)
2531 }
2532
2533 func Connect(fd int, sa Sockaddr) (err error) {
2534 ptr, n, err := sa.sockaddr()
2535 if err != nil {
2536 return err
2537 }
2538 return connect(fd, ptr, n)
2539 }
2540
2541 func Getpeername(fd int) (sa Sockaddr, err error) {
2542 var rsa RawSockaddrAny
2543 var len _Socklen = SizeofSockaddrAny
2544 if err = getpeername(fd, &rsa, &len); err != nil {
2545 return
2546 }
2547 return anyToSockaddr(fd, &rsa)
2548 }
2549
2550 func GetsockoptByte(fd, level, opt int) (value byte, err error) {
2551 var n byte
2552 vallen := _Socklen(1)
2553 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2554 return n, err
2555 }
2556
2557 func GetsockoptInt(fd, level, opt int) (value int, err error) {
2558 var n int32
2559 vallen := _Socklen(4)
2560 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2561 return int(n), err
2562 }
2563
2564 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
2565 vallen := _Socklen(4)
2566 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
2567 return value, err
2568 }
2569
2570 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
2571 var value IPMreq
2572 vallen := _Socklen(SizeofIPMreq)
2573 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2574 return &value, err
2575 }
2576
2577 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
2578 var value IPv6Mreq
2579 vallen := _Socklen(SizeofIPv6Mreq)
2580 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2581 return &value, err
2582 }
2583
2584 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
2585 var value IPv6MTUInfo
2586 vallen := _Socklen(SizeofIPv6MTUInfo)
2587 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2588 return &value, err
2589 }
2590
2591 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
2592 var value ICMPv6Filter
2593 vallen := _Socklen(SizeofICMPv6Filter)
2594 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2595 return &value, err
2596 }
2597
2598 func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
2599 var linger Linger
2600 vallen := _Socklen(SizeofLinger)
2601 err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
2602 return &linger, err
2603 }
2604
2605 func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
2606 var tv Timeval
2607 vallen := _Socklen(unsafe.Sizeof(tv))
2608 err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
2609 return &tv, err
2610 }
2611
2612 func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
2613 var n uint64
2614 vallen := _Socklen(8)
2615 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2616 return n, err
2617 }
2618
2619 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
2620 var rsa RawSockaddrAny
2621 var len _Socklen = SizeofSockaddrAny
2622 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
2623 return
2624 }
2625 if rsa.Addr.Family != AF_UNSPEC {
2626 from, err = anyToSockaddr(fd, &rsa)
2627 }
2628 return
2629 }
2630
2631 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
2632 ptr, n, err := to.sockaddr()
2633 if err != nil {
2634 return err
2635 }
2636 return sendto(fd, p, flags, ptr, n)
2637 }
2638
2639 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
2640 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
2641 }
2642
2643 func SetsockoptInt(fd, level, opt int, value int) (err error) {
2644 var n = int32(value)
2645 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
2646 }
2647
2648 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
2649 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
2650 }
2651
2652 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
2653 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
2654 }
2655
2656 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
2657 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
2658 }
2659
2660 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
2661 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
2662 }
2663
2664 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
2665 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
2666 }
2667
2668 func SetsockoptString(fd, level, opt int, s string) (err error) {
2669 var p unsafe.Pointer
2670 if len(s) > 0 {
2671 p = unsafe.Pointer(&[]byte(s)[0])
2672 }
2673 return setsockopt(fd, level, opt, p, uintptr(len(s)))
2674 }
2675
2676 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
2677 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
2678 }
2679
2680 func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
2681 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
2682 }
2683
2684 func Socket(domain, typ, proto int) (fd int, err error) {
2685 if domain == AF_INET6 && SocketDisableIPv6 {
2686 return -1, EAFNOSUPPORT
2687 }
2688 fd, err = socket(domain, typ, proto)
2689 return
2690 }
2691
2692 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
2693 var fdx [2]int32
2694 err = socketpair(domain, typ, proto, &fdx)
2695 if err == nil {
2696 fd[0] = int(fdx[0])
2697 fd[1] = int(fdx[1])
2698 }
2699 return
2700 }
2701
2702 var ioSync int64
2703
2704 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
2705
2706 func SetNonblock(fd int, nonblocking bool) (err error) {
2707 flag, err := fcntl(fd, F_GETFL, 0)
2708 if err != nil {
2709 return err
2710 }
2711 if nonblocking {
2712 flag |= O_NONBLOCK
2713 } else {
2714 flag &= ^O_NONBLOCK
2715 }
2716 _, err = fcntl(fd, F_SETFL, flag)
2717 return err
2718 }
2719
2720
2721
2722
2723
2724
2725 func Exec(argv0 string, argv []string, envv []string) error {
2726 return syscall.Exec(argv0, argv, envv)
2727 }
2728
2729 func Getag(path string) (ccsid uint16, flag uint16, err error) {
2730 var val [8]byte
2731 sz, err := Getxattr(path, "ccsid", val[:])
2732 if err != nil {
2733 return
2734 }
2735 ccsid = uint16(EncodeData(val[0:sz]))
2736 sz, err = Getxattr(path, "flags", val[:])
2737 if err != nil {
2738 return
2739 }
2740 flag = uint16(EncodeData(val[0:sz]) >> 15)
2741 return
2742 }
2743
2744
2745 func impl_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2746 var _p0 *byte
2747 _p0, err = BytePtrFromString(source)
2748 if err != nil {
2749 return
2750 }
2751 var _p1 *byte
2752 _p1, err = BytePtrFromString(target)
2753 if err != nil {
2754 return
2755 }
2756 var _p2 *byte
2757 _p2, err = BytePtrFromString(fstype)
2758 if err != nil {
2759 return
2760 }
2761 var _p3 *byte
2762 _p3, err = BytePtrFromString(data)
2763 if err != nil {
2764 return
2765 }
2766 runtime.EnterSyscall()
2767 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MOUNT1_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(_p3)))
2768 runtime.ExitSyscall()
2769 if int64(r0) == -1 {
2770 err = errnoErr2(e1, e2)
2771 }
2772 return
2773 }
2774
2775
2776 func get_MountAddr() *(func(source string, target string, fstype string, flags uintptr, data string) (err error))
2777
2778 var Mount = enter_Mount
2779
2780 func enter_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2781 funcref := get_MountAddr()
2782 if validMount() {
2783 *funcref = impl_Mount
2784 } else {
2785 *funcref = legacyMount
2786 }
2787 return (*funcref)(source, target, fstype, flags, data)
2788 }
2789
2790 func legacyMount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2791 if needspace := 8 - len(fstype); needspace <= 0 {
2792 fstype = fstype[0:8]
2793 } else {
2794 fstype += " "[0:needspace]
2795 }
2796 return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
2797 }
2798
2799 func validMount() bool {
2800 if funcptrtest(GetZosLibVec()+SYS___MOUNT1_A<<4, "") == 0 {
2801 if name, err := getLeFuncName(GetZosLibVec() + SYS___MOUNT1_A<<4); err == nil {
2802 return name == "__mount1_a"
2803 }
2804 }
2805 return false
2806 }
2807
2808
2809
2810
2811 func impl_Unmount(target string, flags int) (err error) {
2812 var _p0 *byte
2813 _p0, err = BytePtrFromString(target)
2814 if err != nil {
2815 return
2816 }
2817 runtime.EnterSyscall()
2818 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UMOUNT2_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(flags))
2819 runtime.ExitSyscall()
2820 if int64(r0) == -1 {
2821 err = errnoErr2(e1, e2)
2822 }
2823 return
2824 }
2825
2826
2827 func get_UnmountAddr() *(func(target string, flags int) (err error))
2828
2829 var Unmount = enter_Unmount
2830
2831 func enter_Unmount(target string, flags int) (err error) {
2832 funcref := get_UnmountAddr()
2833 if funcptrtest(GetZosLibVec()+SYS___UMOUNT2_A<<4, "") == 0 {
2834 *funcref = impl_Unmount
2835 } else {
2836 *funcref = legacyUnmount
2837 }
2838 return (*funcref)(target, flags)
2839 }
2840
2841 func legacyUnmount(name string, mtm int) (err error) {
2842
2843
2844 if name[0] != '/' {
2845 return unmount_LE(name, mtm)
2846 }
2847
2848 b2s := func(arr []byte) string {
2849 var str string
2850 for i := 0; i < len(arr); i++ {
2851 if arr[i] == 0 {
2852 str = string(arr[:i])
2853 break
2854 }
2855 }
2856 return str
2857 }
2858 var buffer struct {
2859 header W_Mnth
2860 fsinfo [64]W_Mntent
2861 }
2862 fs_count, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
2863 if err == nil {
2864 err = EINVAL
2865 for i := 0; i < fs_count; i++ {
2866 if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
2867 err = unmount_LE(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
2868 break
2869 }
2870 }
2871 } else if fs_count == 0 {
2872 err = EINVAL
2873 }
2874 return err
2875 }
2876
2877
2878
2879 func direntIno(buf []byte) (uint64, bool) {
2880 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
2881 }
2882
2883 func direntReclen(buf []byte) (uint64, bool) {
2884 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
2885 }
2886
2887 func direntNamlen(buf []byte) (uint64, bool) {
2888 reclen, ok := direntReclen(buf)
2889 if !ok {
2890 return 0, false
2891 }
2892 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
2893 }
2894
2895 func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
2896 var d Dirent
2897
2898 d.Ino = uint64(dirent.Ino)
2899 offset, err := Telldir(dir)
2900 if err != nil {
2901 return d, err
2902 }
2903
2904 d.Off = int64(offset)
2905 s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
2906 copy(d.Name[:], s)
2907
2908 d.Reclen = uint16(24 + len(d.NameString()))
2909 var st Stat_t
2910 path = path + "/" + s
2911 err = Lstat(path, &st)
2912 if err != nil {
2913 return d, err
2914 }
2915
2916 d.Type = uint8(st.Mode >> 24)
2917 return d, err
2918 }
2919
2920 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
2921
2922
2923
2924
2925
2926
2927
2928 skip, err := Seek(fd, 0, 1 )
2929 if err != nil {
2930 return 0, err
2931 }
2932
2933
2934 path, err := ZosFdToPath(fd)
2935 if err != nil {
2936 return 0, err
2937 }
2938 d, err := Opendir(path)
2939 if err != nil {
2940 return 0, err
2941 }
2942 defer Closedir(d)
2943
2944 var cnt int64
2945 for {
2946 var entryLE direntLE
2947 var entrypLE *direntLE
2948 e := Readdir_r(d, &entryLE, &entrypLE)
2949 if e != nil {
2950 return n, e
2951 }
2952 if entrypLE == nil {
2953 break
2954 }
2955 if skip > 0 {
2956 skip--
2957 cnt++
2958 continue
2959 }
2960
2961
2962 entry, e := direntLeToDirentUnix(&entryLE, d, path)
2963 if e != nil {
2964 return n, e
2965 }
2966
2967 reclen := int(entry.Reclen)
2968 if reclen > len(buf) {
2969
2970
2971
2972
2973 break
2974 }
2975
2976
2977 s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
2978 copy(buf, s)
2979
2980 buf = buf[reclen:]
2981 n += reclen
2982 cnt++
2983 }
2984
2985
2986 _, err = Seek(fd, cnt, 0 )
2987 if err != nil {
2988 return n, err
2989 }
2990
2991 return n, nil
2992 }
2993
2994 func Err2ad() (eadd *int) {
2995 r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERR2AD<<4)
2996 eadd = (*int)(unsafe.Pointer(r0))
2997 return
2998 }
2999
3000 func ZosConsolePrintf(format string, v ...interface{}) (int, error) {
3001 type __cmsg struct {
3002 _ uint16
3003 _ [2]uint8
3004 __msg_length uint32
3005 __msg uintptr
3006 _ [4]uint8
3007 }
3008 msg := fmt.Sprintf(format, v...)
3009 strptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&msg)).Data)
3010 len := (*reflect.StringHeader)(unsafe.Pointer(&msg)).Len
3011 cmsg := __cmsg{__msg_length: uint32(len), __msg: uintptr(strptr)}
3012 cmd := uint32(0)
3013 runtime.EnterSyscall()
3014 rc, err2, err1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____CONSOLE_A<<4, uintptr(unsafe.Pointer(&cmsg)), 0, uintptr(unsafe.Pointer(&cmd)))
3015 runtime.ExitSyscall()
3016 if rc != 0 {
3017 return 0, fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
3018 }
3019 return 0, nil
3020 }
3021 func ZosStringToEbcdicBytes(str string, nullterm bool) (ebcdicBytes []byte) {
3022 if nullterm {
3023 ebcdicBytes = []byte(str + "\x00")
3024 } else {
3025 ebcdicBytes = []byte(str)
3026 }
3027 A2e(ebcdicBytes)
3028 return
3029 }
3030 func ZosEbcdicBytesToString(b []byte, trimRight bool) (str string) {
3031 res := make([]byte, len(b))
3032 copy(res, b)
3033 E2a(res)
3034 if trimRight {
3035 str = string(bytes.TrimRight(res, " \x00"))
3036 } else {
3037 str = string(res)
3038 }
3039 return
3040 }
3041
3042 func fdToPath(dirfd int) (path string, err error) {
3043 var buffer [1024]byte
3044
3045 ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
3046 []uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
3047 if ret == 0 {
3048 zb := bytes.IndexByte(buffer[:], 0)
3049 if zb == -1 {
3050 zb = len(buffer)
3051 }
3052
3053 runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
3054 []uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
3055 return string(buffer[:zb]), nil
3056 }
3057
3058 errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
3059 []uintptr{}))))
3060
3061 errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
3062 []uintptr{}))
3063
3064 ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
3065 []uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
3066 if ret == 0 {
3067 zb := bytes.IndexByte(buffer[:], 0)
3068 if zb == -1 {
3069 zb = len(buffer)
3070 }
3071 return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
3072 } else {
3073 return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
3074 }
3075 }
3076
3077 func impl_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3078 var _p0 *byte
3079 _p0, err = BytePtrFromString(path)
3080 if err != nil {
3081 return
3082 }
3083 runtime.EnterSyscall()
3084 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFOAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
3085 runtime.ExitSyscall()
3086 if int64(r0) == -1 {
3087 err = errnoErr2(e1, e2)
3088 }
3089 return
3090 }
3091
3092
3093 func get_MkfifoatAddr() *(func(dirfd int, path string, mode uint32) (err error))
3094
3095 var Mkfifoat = enter_Mkfifoat
3096
3097 func enter_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3098 funcref := get_MkfifoatAddr()
3099 if funcptrtest(GetZosLibVec()+SYS___MKFIFOAT_A<<4, "") == 0 {
3100 *funcref = impl_Mkfifoat
3101 } else {
3102 *funcref = legacy_Mkfifoat
3103 }
3104 return (*funcref)(dirfd, path, mode)
3105 }
3106
3107 func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3108 dirname, err := ZosFdToPath(dirfd)
3109 if err != nil {
3110 return err
3111 }
3112 return Mkfifo(dirname+"/"+path, mode)
3113 }
3114
3115
3116
3117
3118
View as plain text