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 func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
772 xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
773 return unsafe.Pointer(xaddr), err
774 }
775
776 func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
777 return mapper.munmap(uintptr(addr), length)
778 }
779
780
781
782
783
784
785 func Getpgrp() (pid int) {
786 pid, _ = Getpgid(0)
787 return
788 }
789
790
791
792
793
794
795
796 func Getrusage(who int, rusage *Rusage) (err error) {
797 var ruz rusage_zos
798 err = getrusage(who, &ruz)
799
800 rusage.Utime.Sec = ruz.Utime.Sec
801 rusage.Utime.Usec = int64(ruz.Utime.Usec)
802 rusage.Stime.Sec = ruz.Stime.Sec
803 rusage.Stime.Usec = int64(ruz.Stime.Usec)
804 return
805 }
806
807
808
809
810
811
812
813
814
815
816
817
818 func Lstat(path string, stat *Stat_t) (err error) {
819 var statLE Stat_LE_t
820 err = lstat(path, &statLE)
821 copyStat(stat, &statLE)
822 return
823 }
824
825
826 func isSpecialPath(path []byte) (v bool) {
827 var special = [4][8]byte{
828 {'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},
829 {'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},
830 {'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},
831 {'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}
832
833 var i, j int
834 for i = 0; i < len(special); i++ {
835 for j = 0; j < len(special[i]); j++ {
836 if path[j] != special[i][j] {
837 break
838 }
839 }
840 if j == len(special[i]) {
841 return true
842 }
843 }
844 return false
845 }
846
847 func realpath(srcpath string, abspath []byte) (pathlen int, errno int) {
848 var source [1024]byte
849 copy(source[:], srcpath)
850 source[len(srcpath)] = 0
851 ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___REALPATH_A<<4,
852 []uintptr{uintptr(unsafe.Pointer(&source[0])),
853 uintptr(unsafe.Pointer(&abspath[0]))})
854 if ret != 0 {
855 index := bytes.IndexByte(abspath[:], byte(0))
856 if index != -1 {
857 return index, 0
858 }
859 } else {
860 errptr := (*int)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))
861 return 0, *errptr
862 }
863 return 0, 245
864 }
865
866 func Readlink(path string, buf []byte) (n int, err error) {
867 var _p0 *byte
868 _p0, err = BytePtrFromString(path)
869 if err != nil {
870 return
871 }
872 var _p1 unsafe.Pointer
873 if len(buf) > 0 {
874 _p1 = unsafe.Pointer(&buf[0])
875 } else {
876 _p1 = unsafe.Pointer(&_zero)
877 }
878 n = int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___READLINK_A<<4,
879 []uintptr{uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))}))
880 runtime.KeepAlive(unsafe.Pointer(_p0))
881 if n == -1 {
882 value := *(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))
883 err = errnoErr(Errno(value))
884 } else {
885 if buf[0] == '$' {
886 if isSpecialPath(buf[1:9]) {
887 cnt, err1 := realpath(path, buf)
888 if err1 == 0 {
889 n = cnt
890 }
891 }
892 }
893 }
894 return
895 }
896
897 func impl_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
898 var _p0 *byte
899 _p0, err = BytePtrFromString(path)
900 if err != nil {
901 return
902 }
903 var _p1 unsafe.Pointer
904 if len(buf) > 0 {
905 _p1 = unsafe.Pointer(&buf[0])
906 } else {
907 _p1 = unsafe.Pointer(&_zero)
908 }
909 runtime.EnterSyscall()
910 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READLINKAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
911 runtime.ExitSyscall()
912 n = int(r0)
913 if int64(r0) == -1 {
914 err = errnoErr2(e1, e2)
915 return n, err
916 } else {
917 if buf[0] == '$' {
918 if isSpecialPath(buf[1:9]) {
919 cnt, err1 := realpath(path, buf)
920 if err1 == 0 {
921 n = cnt
922 }
923 }
924 }
925 }
926 return
927 }
928
929
930 func get_ReadlinkatAddr() *(func(dirfd int, path string, buf []byte) (n int, err error))
931
932 var Readlinkat = enter_Readlinkat
933
934 func enter_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
935 funcref := get_ReadlinkatAddr()
936 if funcptrtest(GetZosLibVec()+SYS___READLINKAT_A<<4, "") == 0 {
937 *funcref = impl_Readlinkat
938 } else {
939 *funcref = error_Readlinkat
940 }
941 return (*funcref)(dirfd, path, buf)
942 }
943
944 func error_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
945 n = -1
946 err = ENOSYS
947 return
948 }
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980 func Stat(path string, sta *Stat_t) (err error) {
981 var statLE Stat_LE_t
982 err = stat(path, &statLE)
983 copyStat(sta, &statLE)
984 return
985 }
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000 func Open(path string, mode int, perm uint32) (fd int, err error) {
1001 if mode&O_ACCMODE == 0 {
1002 mode |= O_RDONLY
1003 }
1004 return open(path, mode, perm)
1005 }
1006
1007
1008
1009 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
1010 if flags&O_ACCMODE == 0 {
1011 flags |= O_RDONLY
1012 }
1013 return openat(dirfd, path, flags, mode)
1014 }
1015
1016
1017
1018 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
1019 if how.Flags&O_ACCMODE == 0 {
1020 how.Flags |= O_RDONLY
1021 }
1022 return openat2(dirfd, path, how, SizeofOpenHow)
1023 }
1024
1025 func ZosFdToPath(dirfd int) (path string, err error) {
1026 var buffer [1024]byte
1027 runtime.EnterSyscall()
1028 ret, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_W_IOCTL<<4, uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0])))
1029 runtime.ExitSyscall()
1030 if ret == 0 {
1031 zb := bytes.IndexByte(buffer[:], 0)
1032 if zb == -1 {
1033 zb = len(buffer)
1034 }
1035 CallLeFuncWithErr(GetZosLibVec()+SYS___E2A_L<<4, uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb))
1036 return string(buffer[:zb]), nil
1037 }
1038 return "", errnoErr2(e1, e2)
1039 }
1040
1041
1042
1043 func Remove(path string) error {
1044 return remove(path)
1045 }
1046
1047 const ImplementsGetwd = true
1048
1049 func Getcwd(buf []byte) (n int, err error) {
1050 var p unsafe.Pointer
1051 if len(buf) > 0 {
1052 p = unsafe.Pointer(&buf[0])
1053 } else {
1054 p = unsafe.Pointer(&_zero)
1055 }
1056 runtime.EnterSyscall()
1057 r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___GETCWD_A<<4, uintptr(p), uintptr(len(buf)))
1058 runtime.ExitSyscall()
1059 n = clen(buf) + 1
1060 if r0 == 0 {
1061 err = errnoErr2(e1, e2)
1062 }
1063 return
1064 }
1065
1066 func Getwd() (wd string, err error) {
1067 var buf [PathMax]byte
1068 n, err := Getcwd(buf[0:])
1069 if err != nil {
1070 return "", err
1071 }
1072
1073 if n < 1 || n > len(buf) || buf[n-1] != 0 {
1074 return "", EINVAL
1075 }
1076 return string(buf[0 : n-1]), nil
1077 }
1078
1079 func Getgroups() (gids []int, err error) {
1080 n, err := getgroups(0, nil)
1081 if err != nil {
1082 return nil, err
1083 }
1084 if n == 0 {
1085 return nil, nil
1086 }
1087
1088
1089 if n < 0 || n > 1<<20 {
1090 return nil, EINVAL
1091 }
1092
1093 a := make([]_Gid_t, n)
1094 n, err = getgroups(n, &a[0])
1095 if err != nil {
1096 return nil, err
1097 }
1098 gids = make([]int, n)
1099 for i, v := range a[0:n] {
1100 gids[i] = int(v)
1101 }
1102 return
1103 }
1104
1105 func Setgroups(gids []int) (err error) {
1106 if len(gids) == 0 {
1107 return setgroups(0, nil)
1108 }
1109
1110 a := make([]_Gid_t, len(gids))
1111 for i, v := range gids {
1112 a[i] = _Gid_t(v)
1113 }
1114 return setgroups(len(a), &a[0])
1115 }
1116
1117 func gettid() uint64
1118
1119 func Gettid() (tid int) {
1120 return int(gettid())
1121 }
1122
1123 type WaitStatus uint32
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134 const (
1135 mask = 0x7F
1136 core = 0x80
1137 exited = 0x00
1138 stopped = 0x7F
1139 shift = 8
1140 )
1141
1142 func (w WaitStatus) Exited() bool { return w&mask == exited }
1143
1144 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
1145
1146 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
1147
1148 func (w WaitStatus) Continued() bool { return w == 0xFFFF }
1149
1150 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
1151
1152 func (w WaitStatus) ExitStatus() int {
1153 if !w.Exited() {
1154 return -1
1155 }
1156 return int(w>>shift) & 0xFF
1157 }
1158
1159 func (w WaitStatus) Signal() Signal {
1160 if !w.Signaled() {
1161 return -1
1162 }
1163 return Signal(w & mask)
1164 }
1165
1166 func (w WaitStatus) StopSignal() Signal {
1167 if !w.Stopped() {
1168 return -1
1169 }
1170 return Signal(w>>shift) & 0xFF
1171 }
1172
1173 func (w WaitStatus) TrapCause() int { return -1 }
1174
1175
1176
1177 func Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) {
1178 return waitid(idType, id, info, options)
1179 }
1180
1181
1182
1183 func impl_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1184 runtime.EnterSyscall()
1185 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAIT4<<4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)))
1186 runtime.ExitSyscall()
1187 wpid = int(r0)
1188 if int64(r0) == -1 {
1189 err = errnoErr2(e1, e2)
1190 }
1191 return
1192 }
1193
1194
1195 func get_Wait4Addr() *(func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error))
1196
1197 var Wait4 = enter_Wait4
1198
1199 func enter_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1200 funcref := get_Wait4Addr()
1201 if funcptrtest(GetZosLibVec()+SYS_WAIT4<<4, "") == 0 {
1202 *funcref = impl_Wait4
1203 } else {
1204 *funcref = legacyWait4
1205 }
1206 return (*funcref)(pid, wstatus, options, rusage)
1207 }
1208
1209 func legacyWait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
1210
1211
1212 var status _C_int
1213 wpid, err = waitpid(pid, &status, options)
1214 if wstatus != nil {
1215 *wstatus = WaitStatus(status)
1216 }
1217 return
1218 }
1219
1220
1221
1222 func Gettimeofday(tv *Timeval) (err error) {
1223 var tvz timeval_zos
1224 err = gettimeofday(&tvz)
1225 tv.Sec = tvz.Sec
1226 tv.Usec = int64(tvz.Usec)
1227 return
1228 }
1229
1230 func Time(t *Time_t) (tt Time_t, err error) {
1231 var tv Timeval
1232 err = Gettimeofday(&tv)
1233 if err != nil {
1234 return 0, err
1235 }
1236 if t != nil {
1237 *t = Time_t(tv.Sec)
1238 }
1239 return Time_t(tv.Sec), nil
1240 }
1241
1242 func setTimespec(sec, nsec int64) Timespec {
1243 return Timespec{Sec: sec, Nsec: nsec}
1244 }
1245
1246 func setTimeval(sec, usec int64) Timeval {
1247 return Timeval{Sec: sec, Usec: usec}
1248 }
1249
1250
1251
1252 func Pipe(p []int) (err error) {
1253 if len(p) != 2 {
1254 return EINVAL
1255 }
1256 var pp [2]_C_int
1257 err = pipe(&pp)
1258 p[0] = int(pp[0])
1259 p[1] = int(pp[1])
1260 return
1261 }
1262
1263
1264
1265 func Utimes(path string, tv []Timeval) (err error) {
1266 if tv == nil {
1267 return utimes(path, nil)
1268 }
1269 if len(tv) != 2 {
1270 return EINVAL
1271 }
1272 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
1273 }
1274
1275
1276
1277 func validUtimensat() bool {
1278 if funcptrtest(GetZosLibVec()+SYS___UTIMENSAT_A<<4, "") == 0 {
1279 if name, err := getLeFuncName(GetZosLibVec() + SYS___UTIMENSAT_A<<4); err == nil {
1280 return name == "__utimensat_a"
1281 }
1282 }
1283 return false
1284 }
1285
1286
1287
1288
1289 func get_UtimesNanoAddr() *(func(path string, ts []Timespec) (err error))
1290
1291 var UtimesNano = enter_UtimesNano
1292
1293 func enter_UtimesNano(path string, ts []Timespec) (err error) {
1294 funcref := get_UtimesNanoAddr()
1295 if validUtimensat() {
1296 *funcref = utimesNanoImpl
1297 } else {
1298 *funcref = legacyUtimesNano
1299 }
1300 return (*funcref)(path, ts)
1301 }
1302
1303 func utimesNanoImpl(path string, ts []Timespec) (err error) {
1304 if ts == nil {
1305 return utimensat(AT_FDCWD, path, nil, 0)
1306 }
1307 if len(ts) != 2 {
1308 return EINVAL
1309 }
1310 return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
1311 }
1312
1313 func legacyUtimesNano(path string, ts []Timespec) (err error) {
1314 if len(ts) != 2 {
1315 return EINVAL
1316 }
1317
1318
1319 tv := [2]Timeval{
1320 NsecToTimeval(TimespecToNsec(ts[0])),
1321 NsecToTimeval(TimespecToNsec(ts[1])),
1322 }
1323 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
1324 }
1325
1326
1327
1328
1329
1330
1331 func get_UtimesNanoAtAddr() *(func(dirfd int, path string, ts []Timespec, flags int) (err error))
1332
1333 var UtimesNanoAt = enter_UtimesNanoAt
1334
1335 func enter_UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
1336 funcref := get_UtimesNanoAtAddr()
1337 if validUtimensat() {
1338 *funcref = utimesNanoAtImpl
1339 } else {
1340 *funcref = legacyUtimesNanoAt
1341 }
1342 return (*funcref)(dirfd, path, ts, flags)
1343 }
1344
1345 func utimesNanoAtImpl(dirfd int, path string, ts []Timespec, flags int) (err error) {
1346 if ts == nil {
1347 return utimensat(dirfd, path, nil, flags)
1348 }
1349 if len(ts) != 2 {
1350 return EINVAL
1351 }
1352 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
1353 }
1354
1355 func legacyUtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
1356 if path[0] != '/' {
1357 dirPath, err := ZosFdToPath(dirfd)
1358 if err != nil {
1359 return err
1360 }
1361 path = dirPath + "/" + path
1362 }
1363 if flags == AT_SYMLINK_NOFOLLOW {
1364 if len(ts) != 2 {
1365 return EINVAL
1366 }
1367
1368 if ts[0].Nsec >= 5e8 {
1369 ts[0].Sec++
1370 }
1371 ts[0].Nsec = 0
1372 if ts[1].Nsec >= 5e8 {
1373 ts[1].Sec++
1374 }
1375 ts[1].Nsec = 0
1376
1377
1378
1379 tv := []Timeval{
1380 NsecToTimeval(TimespecToNsec(ts[0])),
1381 NsecToTimeval(TimespecToNsec(ts[1])),
1382 }
1383 return Lutimes(path, tv)
1384 }
1385 return UtimesNano(path, ts)
1386 }
1387
1388
1389
1390 func Getsockname(fd int) (sa Sockaddr, err error) {
1391 var rsa RawSockaddrAny
1392 var len _Socklen = SizeofSockaddrAny
1393 if err = getsockname(fd, &rsa, &len); err != nil {
1394 return
1395 }
1396
1397 return anyToSockaddr(0, &rsa)
1398 }
1399
1400 const (
1401
1402 nwmHeaderIdentifier = 0xd5e6d4c8
1403 nwmFilterIdentifier = 0xd5e6d4c6
1404 nwmTCPConnIdentifier = 0xd5e6d4c3
1405 nwmRecHeaderIdentifier = 0xd5e6d4d9
1406 nwmIPStatsIdentifier = 0xd5e6d4c9d7e2e340
1407 nwmIPGStatsIdentifier = 0xd5e6d4c9d7c7e2e3
1408 nwmTCPStatsIdentifier = 0xd5e6d4e3c3d7e2e3
1409 nwmUDPStatsIdentifier = 0xd5e6d4e4c4d7e2e3
1410 nwmICMPGStatsEntry = 0xd5e6d4c9c3d4d7c7
1411 nwmICMPTStatsEntry = 0xd5e6d4c9c3d4d7e3
1412
1413
1414 nwmVersion1 = 1
1415 nwmVersion2 = 2
1416 nwmCurrentVer = 2
1417
1418 nwmTCPConnType = 1
1419 nwmGlobalStatsType = 14
1420
1421
1422 nwmFilterLclAddrMask = 0x20000000
1423 nwmFilterSrcAddrMask = 0x20000000
1424 nwmFilterLclPortMask = 0x10000000
1425 nwmFilterSrcPortMask = 0x10000000
1426
1427
1428 nwmTCPStateClosed = 1
1429 nwmTCPStateListen = 2
1430 nwmTCPStateSynSent = 3
1431 nwmTCPStateSynRcvd = 4
1432 nwmTCPStateEstab = 5
1433 nwmTCPStateFinWait1 = 6
1434 nwmTCPStateFinWait2 = 7
1435 nwmTCPStateClosWait = 8
1436 nwmTCPStateLastAck = 9
1437 nwmTCPStateClosing = 10
1438 nwmTCPStateTimeWait = 11
1439 nwmTCPStateDeletTCB = 12
1440
1441
1442 BPF_TCP_CLOSE = 1
1443 BPF_TCP_LISTEN = 2
1444 BPF_TCP_SYN_SENT = 3
1445 BPF_TCP_SYN_RECV = 4
1446 BPF_TCP_ESTABLISHED = 5
1447 BPF_TCP_FIN_WAIT1 = 6
1448 BPF_TCP_FIN_WAIT2 = 7
1449 BPF_TCP_CLOSE_WAIT = 8
1450 BPF_TCP_LAST_ACK = 9
1451 BPF_TCP_CLOSING = 10
1452 BPF_TCP_TIME_WAIT = 11
1453 BPF_TCP_NEW_SYN_RECV = -1
1454 BPF_TCP_MAX_STATES = -2
1455 )
1456
1457 type nwmTriplet struct {
1458 offset uint32
1459 length uint32
1460 number uint32
1461 }
1462
1463 type nwmQuadruplet struct {
1464 offset uint32
1465 length uint32
1466 number uint32
1467 match uint32
1468 }
1469
1470 type nwmHeader struct {
1471 ident uint32
1472 length uint32
1473 version uint16
1474 nwmType uint16
1475 bytesNeeded uint32
1476 options uint32
1477 _ [16]byte
1478 inputDesc nwmTriplet
1479 outputDesc nwmQuadruplet
1480 }
1481
1482 type nwmFilter struct {
1483 ident uint32
1484 flags uint32
1485 resourceName [8]byte
1486 resourceId uint32
1487 listenerId uint32
1488 local [28]byte
1489 remote [28]byte
1490 _ uint16
1491 _ uint16
1492 asid uint16
1493 _ [2]byte
1494 tnLuName [8]byte
1495 tnMonGrp uint32
1496 tnAppl [8]byte
1497 applData [40]byte
1498 nInterface [16]byte
1499 dVipa [16]byte
1500 dVipaPfx uint16
1501 dVipaPort uint16
1502 dVipaFamily byte
1503 _ [3]byte
1504 destXCF [16]byte
1505 destXCFPfx uint16
1506 destXCFFamily byte
1507 _ [1]byte
1508 targIP [16]byte
1509 targIPPfx uint16
1510 targIPFamily byte
1511 _ [1]byte
1512 _ [20]byte
1513 }
1514
1515 type nwmRecHeader struct {
1516 ident uint32
1517 length uint32
1518 number byte
1519 _ [3]byte
1520 }
1521
1522 type nwmTCPStatsEntry struct {
1523 ident uint64
1524 currEstab uint32
1525 activeOpened uint32
1526 passiveOpened uint32
1527 connClosed uint32
1528 estabResets uint32
1529 attemptFails uint32
1530 passiveDrops uint32
1531 timeWaitReused uint32
1532 inSegs uint64
1533 predictAck uint32
1534 predictData uint32
1535 inDupAck uint32
1536 inBadSum uint32
1537 inBadLen uint32
1538 inShort uint32
1539 inDiscOldTime uint32
1540 inAllBeforeWin uint32
1541 inSomeBeforeWin uint32
1542 inAllAfterWin uint32
1543 inSomeAfterWin uint32
1544 inOutOfOrder uint32
1545 inAfterClose uint32
1546 inWinProbes uint32
1547 inWinUpdates uint32
1548 outWinUpdates uint32
1549 outSegs uint64
1550 outDelayAcks uint32
1551 outRsts uint32
1552 retransSegs uint32
1553 retransTimeouts uint32
1554 retransDrops uint32
1555 pmtuRetrans uint32
1556 pmtuErrors uint32
1557 outWinProbes uint32
1558 probeDrops uint32
1559 keepAliveProbes uint32
1560 keepAliveDrops uint32
1561 finwait2Drops uint32
1562 acceptCount uint64
1563 inBulkQSegs uint64
1564 inDiscards uint64
1565 connFloods uint32
1566 connStalls uint32
1567 cfgEphemDef uint16
1568 ephemInUse uint16
1569 ephemHiWater uint16
1570 flags byte
1571 _ [1]byte
1572 ephemExhaust uint32
1573 smcRCurrEstabLnks uint32
1574 smcRLnkActTimeOut uint32
1575 smcRActLnkOpened uint32
1576 smcRPasLnkOpened uint32
1577 smcRLnksClosed uint32
1578 smcRCurrEstab uint32
1579 smcRActiveOpened uint32
1580 smcRPassiveOpened uint32
1581 smcRConnClosed uint32
1582 smcRInSegs uint64
1583 smcROutSegs uint64
1584 smcRInRsts uint32
1585 smcROutRsts uint32
1586 smcDCurrEstabLnks uint32
1587 smcDActLnkOpened uint32
1588 smcDPasLnkOpened uint32
1589 smcDLnksClosed uint32
1590 smcDCurrEstab uint32
1591 smcDActiveOpened uint32
1592 smcDPassiveOpened uint32
1593 smcDConnClosed uint32
1594 smcDInSegs uint64
1595 smcDOutSegs uint64
1596 smcDInRsts uint32
1597 smcDOutRsts uint32
1598 }
1599
1600 type nwmConnEntry struct {
1601 ident uint32
1602 local [28]byte
1603 remote [28]byte
1604 startTime [8]byte
1605 lastActivity [8]byte
1606 bytesIn [8]byte
1607 bytesOut [8]byte
1608 inSegs [8]byte
1609 outSegs [8]byte
1610 state uint16
1611 activeOpen byte
1612 flag01 byte
1613 outBuffered uint32
1614 inBuffered uint32
1615 maxSndWnd uint32
1616 reXmtCount uint32
1617 congestionWnd uint32
1618 ssThresh uint32
1619 roundTripTime uint32
1620 roundTripVar uint32
1621 sendMSS uint32
1622 sndWnd uint32
1623 rcvBufSize uint32
1624 sndBufSize uint32
1625 outOfOrderCount uint32
1626 lcl0WindowCount uint32
1627 rmt0WindowCount uint32
1628 dupacks uint32
1629 flag02 byte
1630 sockOpt6Cont byte
1631 asid uint16
1632 resourceName [8]byte
1633 resourceId uint32
1634 subtask uint32
1635 sockOpt byte
1636 sockOpt6 byte
1637 clusterConnFlag byte
1638 proto byte
1639 targetAppl [8]byte
1640 luName [8]byte
1641 clientUserId [8]byte
1642 logMode [8]byte
1643 timeStamp uint32
1644 timeStampAge uint32
1645 serverResourceId uint32
1646 intfName [16]byte
1647 ttlsStatPol byte
1648 ttlsStatConn byte
1649 ttlsSSLProt uint16
1650 ttlsNegCiph [2]byte
1651 ttlsSecType byte
1652 ttlsFIPS140Mode byte
1653 ttlsUserID [8]byte
1654 applData [40]byte
1655 inOldestTime [8]byte
1656 outOldestTime [8]byte
1657 tcpTrustedPartner byte
1658 _ [3]byte
1659 bulkDataIntfName [16]byte
1660 ttlsNegCiph4 [4]byte
1661 smcReason uint32
1662 lclSMCLinkId uint32
1663 rmtSMCLinkId uint32
1664 smcStatus byte
1665 smcFlags byte
1666 _ [2]byte
1667 rcvWnd uint32
1668 lclSMCBufSz uint32
1669 rmtSMCBufSz uint32
1670 ttlsSessID [32]byte
1671 ttlsSessIDLen int16
1672 _ [1]byte
1673 smcDStatus byte
1674 smcDReason uint32
1675 }
1676
1677 var svcNameTable [][]byte = [][]byte{
1678 []byte("\xc5\xe9\xc2\xd5\xd4\xc9\xc6\xf4"),
1679 }
1680
1681 const (
1682 svc_EZBNMIF4 = 0
1683 )
1684
1685 func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
1686 jobname := []byte("\x5c\x40\x40\x40\x40\x40\x40\x40")
1687 responseBuffer := [4096]byte{0}
1688 var bufferAlet, reasonCode uint32 = 0, 0
1689 var bufferLen, returnValue, returnCode int32 = 4096, 0, 0
1690
1691 dsa := [18]uint64{0}
1692 var argv [7]unsafe.Pointer
1693 argv[0] = unsafe.Pointer(&jobname[0])
1694 argv[1] = unsafe.Pointer(&responseBuffer[0])
1695 argv[2] = unsafe.Pointer(&bufferAlet)
1696 argv[3] = unsafe.Pointer(&bufferLen)
1697 argv[4] = unsafe.Pointer(&returnValue)
1698 argv[5] = unsafe.Pointer(&returnCode)
1699 argv[6] = unsafe.Pointer(&reasonCode)
1700
1701 request := (*struct {
1702 header nwmHeader
1703 filter nwmFilter
1704 })(unsafe.Pointer(&responseBuffer[0]))
1705
1706 EZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])
1707 if EZBNMIF4 == nil {
1708 return nil, errnoErr(EINVAL)
1709 }
1710
1711
1712 request.header.ident = nwmHeaderIdentifier
1713 request.header.length = uint32(unsafe.Sizeof(request.header))
1714 request.header.version = nwmCurrentVer
1715 request.header.nwmType = nwmGlobalStatsType
1716 request.header.options = 0x80000000
1717
1718 svcCall(EZBNMIF4, &argv[0], &dsa[0])
1719
1720
1721 if returnCode != 0 || request.header.outputDesc.offset == 0 {
1722 return nil, errnoErr(EINVAL)
1723 }
1724
1725
1726 recHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
1727 if recHeader.ident != nwmRecHeaderIdentifier {
1728 return nil, errnoErr(EINVAL)
1729 }
1730
1731
1732 var sections []*uint64
1733 var sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))
1734 for i := uint32(0); i < uint32(recHeader.number); i++ {
1735 offset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))
1736 sectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))
1737 for j := uint32(0); j < sectionDesc.number; j++ {
1738 offset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length
1739 sections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))
1740 }
1741 }
1742
1743
1744 var tcpStats *nwmTCPStatsEntry = nil
1745 for _, ptr := range sections {
1746 switch *ptr {
1747 case nwmTCPStatsIdentifier:
1748 if tcpStats != nil {
1749 return nil, errnoErr(EINVAL)
1750 }
1751 tcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))
1752 case nwmIPStatsIdentifier:
1753 case nwmIPGStatsIdentifier:
1754 case nwmUDPStatsIdentifier:
1755 case nwmICMPGStatsEntry:
1756 case nwmICMPTStatsEntry:
1757 default:
1758 return nil, errnoErr(EINVAL)
1759 }
1760 }
1761 if tcpStats == nil {
1762 return nil, errnoErr(EINVAL)
1763 }
1764
1765
1766 responseBuffer = [4096]byte{0}
1767 dsa = [18]uint64{0}
1768 bufferAlet, reasonCode = 0, 0
1769 bufferLen, returnValue, returnCode = 4096, 0, 0
1770 nameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c)))
1771 nameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))
1772 argv[0] = unsafe.Pointer(uintptr(*nameptr))
1773
1774 request.header.ident = nwmHeaderIdentifier
1775 request.header.length = uint32(unsafe.Sizeof(request.header))
1776 request.header.version = nwmCurrentVer
1777 request.header.nwmType = nwmTCPConnType
1778 request.header.options = 0x80000000
1779
1780 request.filter.ident = nwmFilterIdentifier
1781
1782 var localSockaddr RawSockaddrAny
1783 socklen := _Socklen(SizeofSockaddrAny)
1784 err := getsockname(fd, &localSockaddr, &socklen)
1785 if err != nil {
1786 return nil, errnoErr(EINVAL)
1787 }
1788 if localSockaddr.Addr.Family == AF_INET {
1789 localSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))
1790 localSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))
1791 localSockFilter.Family = AF_INET
1792 var i int
1793 for i = 0; i < 4; i++ {
1794 if localSockaddr.Addr[i] != 0 {
1795 break
1796 }
1797 }
1798 if i != 4 {
1799 request.filter.flags |= nwmFilterLclAddrMask
1800 for i = 0; i < 4; i++ {
1801 localSockFilter.Addr[i] = localSockaddr.Addr[i]
1802 }
1803 }
1804 if localSockaddr.Port != 0 {
1805 request.filter.flags |= nwmFilterLclPortMask
1806 localSockFilter.Port = localSockaddr.Port
1807 }
1808 } else if localSockaddr.Addr.Family == AF_INET6 {
1809 localSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))
1810 localSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))
1811 localSockFilter.Family = AF_INET6
1812 var i int
1813 for i = 0; i < 16; i++ {
1814 if localSockaddr.Addr[i] != 0 {
1815 break
1816 }
1817 }
1818 if i != 16 {
1819 request.filter.flags |= nwmFilterLclAddrMask
1820 for i = 0; i < 16; i++ {
1821 localSockFilter.Addr[i] = localSockaddr.Addr[i]
1822 }
1823 }
1824 if localSockaddr.Port != 0 {
1825 request.filter.flags |= nwmFilterLclPortMask
1826 localSockFilter.Port = localSockaddr.Port
1827 }
1828 }
1829
1830 svcCall(EZBNMIF4, &argv[0], &dsa[0])
1831
1832
1833 if returnCode != 0 || request.header.outputDesc.offset == 0 {
1834 return nil, errnoErr(EINVAL)
1835 }
1836
1837
1838 conn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))
1839 if conn.ident != nwmTCPConnIdentifier {
1840 return nil, errnoErr(EINVAL)
1841 }
1842
1843
1844
1845
1846
1847 var tcpinfo TCPInfo
1848 tcpinfo.State = uint8(conn.state)
1849 tcpinfo.Ca_state = 0
1850 tcpinfo.Retransmits = uint8(tcpStats.retransSegs)
1851 tcpinfo.Probes = uint8(tcpStats.outWinProbes)
1852 tcpinfo.Backoff = 0
1853 tcpinfo.Options = 0
1854 tcpinfo.Rto = tcpStats.retransTimeouts
1855 tcpinfo.Ato = tcpStats.outDelayAcks
1856 tcpinfo.Snd_mss = conn.sendMSS
1857 tcpinfo.Rcv_mss = conn.sendMSS
1858 tcpinfo.Unacked = 0
1859 tcpinfo.Sacked = 0
1860 tcpinfo.Lost = 0
1861 tcpinfo.Retrans = conn.reXmtCount
1862 tcpinfo.Fackets = 0
1863 tcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))
1864 tcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))
1865 tcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
1866 tcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))
1867 tcpinfo.Pmtu = conn.sendMSS
1868 tcpinfo.Rcv_ssthresh = conn.ssThresh
1869 tcpinfo.Rtt = conn.roundTripTime
1870 tcpinfo.Rttvar = conn.roundTripVar
1871 tcpinfo.Snd_ssthresh = conn.ssThresh
1872 tcpinfo.Snd_cwnd = conn.congestionWnd
1873 tcpinfo.Advmss = conn.sendMSS
1874 tcpinfo.Reordering = 0
1875 tcpinfo.Rcv_rtt = conn.roundTripTime
1876 tcpinfo.Rcv_space = conn.sendMSS
1877 tcpinfo.Total_retrans = conn.reXmtCount
1878
1879 svcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)
1880
1881 return &tcpinfo, nil
1882 }
1883
1884
1885
1886 func GetsockoptString(fd, level, opt int) (string, error) {
1887 buf := make([]byte, 256)
1888 vallen := _Socklen(len(buf))
1889 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
1890 if err != nil {
1891 return "", err
1892 }
1893
1894 return ByteSliceToString(buf[:vallen]), nil
1895 }
1896
1897 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
1898 var msg Msghdr
1899 var rsa RawSockaddrAny
1900 msg.Name = (*byte)(unsafe.Pointer(&rsa))
1901 msg.Namelen = SizeofSockaddrAny
1902 var iov Iovec
1903 if len(p) > 0 {
1904 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
1905 iov.SetLen(len(p))
1906 }
1907 var dummy byte
1908 if len(oob) > 0 {
1909
1910 if len(p) == 0 {
1911 iov.Base = &dummy
1912 iov.SetLen(1)
1913 }
1914 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
1915 msg.SetControllen(len(oob))
1916 }
1917 msg.Iov = &iov
1918 msg.Iovlen = 1
1919 if n, err = recvmsg(fd, &msg, flags); err != nil {
1920 return
1921 }
1922 oobn = int(msg.Controllen)
1923 recvflags = int(msg.Flags)
1924
1925 if rsa.Addr.Family != AF_UNSPEC {
1926
1927 from, err = anyToSockaddr(0, &rsa)
1928 }
1929 return
1930 }
1931
1932 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
1933 _, err = SendmsgN(fd, p, oob, to, flags)
1934 return
1935 }
1936
1937 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
1938 var ptr unsafe.Pointer
1939 var salen _Socklen
1940 if to != nil {
1941 var err error
1942 ptr, salen, err = to.sockaddr()
1943 if err != nil {
1944 return 0, err
1945 }
1946 }
1947 var msg Msghdr
1948 msg.Name = (*byte)(unsafe.Pointer(ptr))
1949 msg.Namelen = int32(salen)
1950 var iov Iovec
1951 if len(p) > 0 {
1952 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
1953 iov.SetLen(len(p))
1954 }
1955 var dummy byte
1956 if len(oob) > 0 {
1957
1958 if len(p) == 0 {
1959 iov.Base = &dummy
1960 iov.SetLen(1)
1961 }
1962 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
1963 msg.SetControllen(len(oob))
1964 }
1965 msg.Iov = &iov
1966 msg.Iovlen = 1
1967 if n, err = sendmsg(fd, &msg, flags); err != nil {
1968 return 0, err
1969 }
1970 if len(oob) > 0 && len(p) == 0 {
1971 n = 0
1972 }
1973 return n, nil
1974 }
1975
1976 func Opendir(name string) (uintptr, error) {
1977 p, err := BytePtrFromString(name)
1978 if err != nil {
1979 return 0, err
1980 }
1981 err = nil
1982 runtime.EnterSyscall()
1983 dir, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___OPENDIR_A<<4, uintptr(unsafe.Pointer(p)))
1984 runtime.ExitSyscall()
1985 runtime.KeepAlive(unsafe.Pointer(p))
1986 if dir == 0 {
1987 err = errnoErr2(e1, e2)
1988 }
1989 return dir, err
1990 }
1991
1992
1993 func clearErrno()
1994
1995 func Closedir(dir uintptr) error {
1996 runtime.EnterSyscall()
1997 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSEDIR<<4, dir)
1998 runtime.ExitSyscall()
1999 if r0 != 0 {
2000 return errnoErr2(e1, e2)
2001 }
2002 return nil
2003 }
2004
2005 func Seekdir(dir uintptr, pos int) {
2006 runtime.EnterSyscall()
2007 CallLeFuncWithErr(GetZosLibVec()+SYS_SEEKDIR<<4, dir, uintptr(pos))
2008 runtime.ExitSyscall()
2009 }
2010
2011 func Telldir(dir uintptr) (int, error) {
2012 p, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TELLDIR<<4, dir)
2013 pos := int(p)
2014 if int64(p) == -1 {
2015 return pos, errnoErr2(e1, e2)
2016 }
2017 return pos, nil
2018 }
2019
2020
2021 func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
2022
2023
2024 var flock [24]byte
2025 *(*int16)(unsafe.Pointer(&flock[0])) = lk.Type
2026 *(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence
2027 *(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
2028 *(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
2029 *(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
2030 runtime.EnterSyscall()
2031 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
2032 runtime.ExitSyscall()
2033 lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
2034 lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
2035 lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
2036 lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
2037 lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
2038 if r0 == 0 {
2039 return nil
2040 }
2041 return errnoErr2(e1, e2)
2042 }
2043
2044 func impl_Flock(fd int, how int) (err error) {
2045 runtime.EnterSyscall()
2046 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FLOCK<<4, uintptr(fd), uintptr(how))
2047 runtime.ExitSyscall()
2048 if int64(r0) == -1 {
2049 err = errnoErr2(e1, e2)
2050 }
2051 return
2052 }
2053
2054
2055 func get_FlockAddr() *(func(fd int, how int) (err error))
2056
2057 var Flock = enter_Flock
2058
2059 func validFlock(fp uintptr) bool {
2060 if funcptrtest(GetZosLibVec()+SYS_FLOCK<<4, "") == 0 {
2061 if name, err := getLeFuncName(GetZosLibVec() + SYS_FLOCK<<4); err == nil {
2062 return name == "flock"
2063 }
2064 }
2065 return false
2066 }
2067
2068 func enter_Flock(fd int, how int) (err error) {
2069 funcref := get_FlockAddr()
2070 if validFlock(GetZosLibVec() + SYS_FLOCK<<4) {
2071 *funcref = impl_Flock
2072 } else {
2073 *funcref = legacyFlock
2074 }
2075 return (*funcref)(fd, how)
2076 }
2077
2078 func legacyFlock(fd int, how int) error {
2079
2080 var flock_type int16
2081 var fcntl_cmd int
2082
2083 switch how {
2084 case LOCK_SH | LOCK_NB:
2085 flock_type = F_RDLCK
2086 fcntl_cmd = F_SETLK
2087 case LOCK_EX | LOCK_NB:
2088 flock_type = F_WRLCK
2089 fcntl_cmd = F_SETLK
2090 case LOCK_EX:
2091 flock_type = F_WRLCK
2092 fcntl_cmd = F_SETLKW
2093 case LOCK_UN:
2094 flock_type = F_UNLCK
2095 fcntl_cmd = F_SETLKW
2096 default:
2097 }
2098
2099 flock := Flock_t{
2100 Type: int16(flock_type),
2101 Whence: int16(0),
2102 Start: int64(0),
2103 Len: int64(0),
2104 Pid: int32(Getppid()),
2105 }
2106
2107 err := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)
2108 return err
2109 }
2110
2111 func Mlock(b []byte) (err error) {
2112 runtime.EnterSyscall()
2113 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2114 runtime.ExitSyscall()
2115 if r0 != 0 {
2116 err = errnoErr2(e1, e2)
2117 }
2118 return
2119 }
2120
2121 func Mlock2(b []byte, flags int) (err error) {
2122 runtime.EnterSyscall()
2123 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2124 runtime.ExitSyscall()
2125 if r0 != 0 {
2126 err = errnoErr2(e1, e2)
2127 }
2128 return
2129 }
2130
2131 func Mlockall(flags int) (err error) {
2132 runtime.EnterSyscall()
2133 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
2134 runtime.ExitSyscall()
2135 if r0 != 0 {
2136 err = errnoErr2(e1, e2)
2137 }
2138 return
2139 }
2140
2141 func Munlock(b []byte) (err error) {
2142 runtime.EnterSyscall()
2143 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
2144 runtime.ExitSyscall()
2145 if r0 != 0 {
2146 err = errnoErr2(e1, e2)
2147 }
2148 return
2149 }
2150
2151 func Munlockall() (err error) {
2152 runtime.EnterSyscall()
2153 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
2154 runtime.ExitSyscall()
2155 if r0 != 0 {
2156 err = errnoErr2(e1, e2)
2157 }
2158 return
2159 }
2160
2161 func ClockGettime(clockid int32, ts *Timespec) error {
2162
2163 var ticks_per_sec uint32 = 100
2164 var nsec_per_sec int64 = 1000000000
2165
2166 if ts == nil {
2167 return EFAULT
2168 }
2169 if clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {
2170 var nanotime int64 = runtime.Nanotime1()
2171 ts.Sec = nanotime / nsec_per_sec
2172 ts.Nsec = nanotime % nsec_per_sec
2173 } else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {
2174 var tm Tms
2175 _, err := Times(&tm)
2176 if err != nil {
2177 return EFAULT
2178 }
2179 ts.Sec = int64(tm.Utime / ticks_per_sec)
2180 ts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)
2181 } else {
2182 return EINVAL
2183 }
2184 return nil
2185 }
2186
2187
2188
2189
2190 func get_ChtagAddr() *(func(path string, ccsid uint64, textbit uint64) error)
2191
2192 var Chtag = enter_Chtag
2193
2194 func enter_Chtag(path string, ccsid uint64, textbit uint64) error {
2195 funcref := get_ChtagAddr()
2196 if validSetxattr() {
2197 *funcref = impl_Chtag
2198 } else {
2199 *funcref = legacy_Chtag
2200 }
2201 return (*funcref)(path, ccsid, textbit)
2202 }
2203
2204 func legacy_Chtag(path string, ccsid uint64, textbit uint64) error {
2205 tag := ccsid<<16 | textbit<<15
2206 var tag_buff [8]byte
2207 DecodeData(tag_buff[:], 8, tag)
2208 return Setxattr(path, "filetag", tag_buff[:], XATTR_REPLACE)
2209 }
2210
2211 func impl_Chtag(path string, ccsid uint64, textbit uint64) error {
2212 tag := ccsid<<16 | textbit<<15
2213 var tag_buff [4]byte
2214 DecodeData(tag_buff[:], 4, tag)
2215 return Setxattr(path, "system.filetag", tag_buff[:], XATTR_REPLACE)
2216 }
2217
2218
2219
2220
2221
2222
2223 func get_NanosleepAddr() *(func(time *Timespec, leftover *Timespec) error)
2224
2225 var Nanosleep = enter_Nanosleep
2226
2227 func enter_Nanosleep(time *Timespec, leftover *Timespec) error {
2228 funcref := get_NanosleepAddr()
2229 if funcptrtest(GetZosLibVec()+SYS_NANOSLEEP<<4, "") == 0 {
2230 *funcref = impl_Nanosleep
2231 } else {
2232 *funcref = legacyNanosleep
2233 }
2234 return (*funcref)(time, leftover)
2235 }
2236
2237 func impl_Nanosleep(time *Timespec, leftover *Timespec) error {
2238 runtime.EnterSyscall()
2239 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_NANOSLEEP<<4, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)))
2240 runtime.ExitSyscall()
2241 if int64(r0) == -1 {
2242 return errnoErr2(e1, e2)
2243 }
2244 return nil
2245 }
2246
2247 func legacyNanosleep(time *Timespec, leftover *Timespec) error {
2248 t0 := runtime.Nanotime1()
2249 var secrem uint32
2250 var nsecrem uint32
2251 total := time.Sec*1000000000 + time.Nsec
2252 elapsed := runtime.Nanotime1() - t0
2253 var rv int32
2254 var rc int32
2255 var err error
2256
2257 for total-elapsed > 1000000000 {
2258 rv, rc, _ = BpxCondTimedWait(uint32(1), uint32(0), uint32(CW_CONDVAR), &secrem, &nsecrem)
2259 if rv != 0 && rc != 112 {
2260 if leftover != nil && rc == 120 {
2261 leftover.Sec = int64(secrem)
2262 leftover.Nsec = int64(nsecrem)
2263 }
2264 err = Errno(rc)
2265 return err
2266 }
2267 elapsed = runtime.Nanotime1() - t0
2268 }
2269
2270 if total > elapsed {
2271 rv, rc, _ = BpxCondTimedWait(uint32(0), uint32(total-elapsed), uint32(CW_CONDVAR), &secrem, &nsecrem)
2272 }
2273 if leftover != nil && rc == 120 {
2274 leftover.Sec = int64(secrem)
2275 leftover.Nsec = int64(nsecrem)
2276 }
2277 if rv != 0 && rc != 112 {
2278 err = Errno(rc)
2279 }
2280 return err
2281 }
2282
2283
2284
2285 var (
2286 Stdin = 0
2287 Stdout = 1
2288 Stderr = 2
2289 )
2290
2291
2292
2293 var (
2294 errEAGAIN error = syscall.EAGAIN
2295 errEINVAL error = syscall.EINVAL
2296 errENOENT error = syscall.ENOENT
2297 )
2298
2299 var ZosTraceLevel int
2300 var ZosTracefile *os.File
2301
2302 var (
2303 signalNameMapOnce sync.Once
2304 signalNameMap map[string]syscall.Signal
2305 )
2306
2307
2308
2309 func errnoErr(e Errno) error {
2310 switch e {
2311 case 0:
2312 return nil
2313 case EAGAIN:
2314 return errEAGAIN
2315 case EINVAL:
2316 return errEINVAL
2317 case ENOENT:
2318 return errENOENT
2319 }
2320 return e
2321 }
2322
2323 var reg *regexp.Regexp
2324
2325
2326 func errnoErr2(e Errno, e2 uintptr) error {
2327 switch e {
2328 case 0:
2329 return nil
2330 case EAGAIN:
2331 return errEAGAIN
2332
2339 }
2340 if ZosTraceLevel > 0 {
2341 var name string
2342 if reg == nil {
2343 reg = regexp.MustCompile("(^unix\\.[^/]+$|.*\\/unix\\.[^/]+$)")
2344 }
2345 i := 1
2346 pc, file, line, ok := runtime.Caller(i)
2347 if ok {
2348 name = runtime.FuncForPC(pc).Name()
2349 }
2350 for ok && reg.MatchString(runtime.FuncForPC(pc).Name()) {
2351 i += 1
2352 pc, file, line, ok = runtime.Caller(i)
2353 }
2354 if ok {
2355 if ZosTracefile == nil {
2356 ZosConsolePrintf("From %s:%d\n", file, line)
2357 ZosConsolePrintf("%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
2358 } else {
2359 fmt.Fprintf(ZosTracefile, "From %s:%d\n", file, line)
2360 fmt.Fprintf(ZosTracefile, "%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
2361 }
2362 } else {
2363 if ZosTracefile == nil {
2364 ZosConsolePrintf("%s (errno2=0x%x)\n", e.Error(), e2)
2365 } else {
2366 fmt.Fprintf(ZosTracefile, "%s (errno2=0x%x)\n", e.Error(), e2)
2367 }
2368 }
2369 }
2370 return e
2371 }
2372
2373
2374 func ErrnoName(e Errno) string {
2375 i := sort.Search(len(errorList), func(i int) bool {
2376 return errorList[i].num >= e
2377 })
2378 if i < len(errorList) && errorList[i].num == e {
2379 return errorList[i].name
2380 }
2381 return ""
2382 }
2383
2384
2385 func SignalName(s syscall.Signal) string {
2386 i := sort.Search(len(signalList), func(i int) bool {
2387 return signalList[i].num >= s
2388 })
2389 if i < len(signalList) && signalList[i].num == s {
2390 return signalList[i].name
2391 }
2392 return ""
2393 }
2394
2395
2396
2397
2398 func SignalNum(s string) syscall.Signal {
2399 signalNameMapOnce.Do(func() {
2400 signalNameMap = make(map[string]syscall.Signal, len(signalList))
2401 for _, signal := range signalList {
2402 signalNameMap[signal.name] = signal.num
2403 }
2404 })
2405 return signalNameMap[s]
2406 }
2407
2408
2409 func clen(n []byte) int {
2410 i := bytes.IndexByte(n, 0)
2411 if i == -1 {
2412 i = len(n)
2413 }
2414 return i
2415 }
2416
2417
2418
2419 type mmapper struct {
2420 sync.Mutex
2421 active map[*byte][]byte
2422 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
2423 munmap func(addr uintptr, length uintptr) error
2424 }
2425
2426 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
2427 if length <= 0 {
2428 return nil, EINVAL
2429 }
2430
2431
2432 flags |= __MAP_64
2433
2434
2435 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
2436 if errno != nil {
2437 return nil, errno
2438 }
2439
2440
2441 var sl = struct {
2442 addr uintptr
2443 len int
2444 cap int
2445 }{addr, length, length}
2446
2447
2448 b := *(*[]byte)(unsafe.Pointer(&sl))
2449
2450
2451 p := &b[cap(b)-1]
2452 m.Lock()
2453 defer m.Unlock()
2454 m.active[p] = b
2455 return b, nil
2456 }
2457
2458 func (m *mmapper) Munmap(data []byte) (err error) {
2459 if len(data) == 0 || len(data) != cap(data) {
2460 return EINVAL
2461 }
2462
2463
2464 p := &data[cap(data)-1]
2465 m.Lock()
2466 defer m.Unlock()
2467 b := m.active[p]
2468 if b == nil || &b[0] != &data[0] {
2469 return EINVAL
2470 }
2471
2472
2473 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
2474 return errno
2475 }
2476 delete(m.active, p)
2477 return nil
2478 }
2479
2480 func Read(fd int, p []byte) (n int, err error) {
2481 n, err = read(fd, p)
2482 if raceenabled {
2483 if n > 0 {
2484 raceWriteRange(unsafe.Pointer(&p[0]), n)
2485 }
2486 if err == nil {
2487 raceAcquire(unsafe.Pointer(&ioSync))
2488 }
2489 }
2490 return
2491 }
2492
2493 func Write(fd int, p []byte) (n int, err error) {
2494 if raceenabled {
2495 raceReleaseMerge(unsafe.Pointer(&ioSync))
2496 }
2497 n, err = write(fd, p)
2498 if raceenabled && n > 0 {
2499 raceReadRange(unsafe.Pointer(&p[0]), n)
2500 }
2501 return
2502 }
2503
2504
2505
2506 var SocketDisableIPv6 bool
2507
2508
2509 type Sockaddr interface {
2510 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
2511 }
2512
2513
2514 type SockaddrInet4 struct {
2515 Port int
2516 Addr [4]byte
2517 raw RawSockaddrInet4
2518 }
2519
2520
2521 type SockaddrInet6 struct {
2522 Port int
2523 ZoneId uint32
2524 Addr [16]byte
2525 raw RawSockaddrInet6
2526 }
2527
2528
2529 type SockaddrUnix struct {
2530 Name string
2531 raw RawSockaddrUnix
2532 }
2533
2534 func Bind(fd int, sa Sockaddr) (err error) {
2535 ptr, n, err := sa.sockaddr()
2536 if err != nil {
2537 return err
2538 }
2539 return bind(fd, ptr, n)
2540 }
2541
2542 func Connect(fd int, sa Sockaddr) (err error) {
2543 ptr, n, err := sa.sockaddr()
2544 if err != nil {
2545 return err
2546 }
2547 return connect(fd, ptr, n)
2548 }
2549
2550 func Getpeername(fd int) (sa Sockaddr, err error) {
2551 var rsa RawSockaddrAny
2552 var len _Socklen = SizeofSockaddrAny
2553 if err = getpeername(fd, &rsa, &len); err != nil {
2554 return
2555 }
2556 return anyToSockaddr(fd, &rsa)
2557 }
2558
2559 func GetsockoptByte(fd, level, opt int) (value byte, err error) {
2560 var n byte
2561 vallen := _Socklen(1)
2562 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2563 return n, err
2564 }
2565
2566 func GetsockoptInt(fd, level, opt int) (value int, err error) {
2567 var n int32
2568 vallen := _Socklen(4)
2569 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2570 return int(n), err
2571 }
2572
2573 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
2574 vallen := _Socklen(4)
2575 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
2576 return value, err
2577 }
2578
2579 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
2580 var value IPMreq
2581 vallen := _Socklen(SizeofIPMreq)
2582 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2583 return &value, err
2584 }
2585
2586 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
2587 var value IPv6Mreq
2588 vallen := _Socklen(SizeofIPv6Mreq)
2589 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2590 return &value, err
2591 }
2592
2593 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
2594 var value IPv6MTUInfo
2595 vallen := _Socklen(SizeofIPv6MTUInfo)
2596 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2597 return &value, err
2598 }
2599
2600 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
2601 var value ICMPv6Filter
2602 vallen := _Socklen(SizeofICMPv6Filter)
2603 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
2604 return &value, err
2605 }
2606
2607 func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
2608 var linger Linger
2609 vallen := _Socklen(SizeofLinger)
2610 err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
2611 return &linger, err
2612 }
2613
2614 func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
2615 var tv Timeval
2616 vallen := _Socklen(unsafe.Sizeof(tv))
2617 err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
2618 return &tv, err
2619 }
2620
2621 func GetsockoptUint64(fd, level, opt int) (value uint64, err error) {
2622 var n uint64
2623 vallen := _Socklen(8)
2624 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
2625 return n, err
2626 }
2627
2628 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
2629 var rsa RawSockaddrAny
2630 var len _Socklen = SizeofSockaddrAny
2631 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
2632 return
2633 }
2634 if rsa.Addr.Family != AF_UNSPEC {
2635 from, err = anyToSockaddr(fd, &rsa)
2636 }
2637 return
2638 }
2639
2640 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
2641 ptr, n, err := to.sockaddr()
2642 if err != nil {
2643 return err
2644 }
2645 return sendto(fd, p, flags, ptr, n)
2646 }
2647
2648 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
2649 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
2650 }
2651
2652 func SetsockoptInt(fd, level, opt int, value int) (err error) {
2653 var n = int32(value)
2654 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
2655 }
2656
2657 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
2658 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
2659 }
2660
2661 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
2662 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
2663 }
2664
2665 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
2666 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
2667 }
2668
2669 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
2670 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
2671 }
2672
2673 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
2674 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
2675 }
2676
2677 func SetsockoptString(fd, level, opt int, s string) (err error) {
2678 var p unsafe.Pointer
2679 if len(s) > 0 {
2680 p = unsafe.Pointer(&[]byte(s)[0])
2681 }
2682 return setsockopt(fd, level, opt, p, uintptr(len(s)))
2683 }
2684
2685 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
2686 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
2687 }
2688
2689 func SetsockoptUint64(fd, level, opt int, value uint64) (err error) {
2690 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)
2691 }
2692
2693 func Socket(domain, typ, proto int) (fd int, err error) {
2694 if domain == AF_INET6 && SocketDisableIPv6 {
2695 return -1, EAFNOSUPPORT
2696 }
2697 fd, err = socket(domain, typ, proto)
2698 return
2699 }
2700
2701 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
2702 var fdx [2]int32
2703 err = socketpair(domain, typ, proto, &fdx)
2704 if err == nil {
2705 fd[0] = int(fdx[0])
2706 fd[1] = int(fdx[1])
2707 }
2708 return
2709 }
2710
2711 var ioSync int64
2712
2713 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
2714
2715 func SetNonblock(fd int, nonblocking bool) (err error) {
2716 flag, err := fcntl(fd, F_GETFL, 0)
2717 if err != nil {
2718 return err
2719 }
2720 if nonblocking {
2721 flag |= O_NONBLOCK
2722 } else {
2723 flag &= ^O_NONBLOCK
2724 }
2725 _, err = fcntl(fd, F_SETFL, flag)
2726 return err
2727 }
2728
2729
2730
2731
2732
2733
2734 func Exec(argv0 string, argv []string, envv []string) error {
2735 return syscall.Exec(argv0, argv, envv)
2736 }
2737
2738 func Getag(path string) (ccsid uint16, flag uint16, err error) {
2739 var val [8]byte
2740 sz, err := Getxattr(path, "ccsid", val[:])
2741 if err != nil {
2742 return
2743 }
2744 ccsid = uint16(EncodeData(val[0:sz]))
2745 sz, err = Getxattr(path, "flags", val[:])
2746 if err != nil {
2747 return
2748 }
2749 flag = uint16(EncodeData(val[0:sz]) >> 15)
2750 return
2751 }
2752
2753
2754 func impl_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2755 var _p0 *byte
2756 _p0, err = BytePtrFromString(source)
2757 if err != nil {
2758 return
2759 }
2760 var _p1 *byte
2761 _p1, err = BytePtrFromString(target)
2762 if err != nil {
2763 return
2764 }
2765 var _p2 *byte
2766 _p2, err = BytePtrFromString(fstype)
2767 if err != nil {
2768 return
2769 }
2770 var _p3 *byte
2771 _p3, err = BytePtrFromString(data)
2772 if err != nil {
2773 return
2774 }
2775 runtime.EnterSyscall()
2776 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)))
2777 runtime.ExitSyscall()
2778 if int64(r0) == -1 {
2779 err = errnoErr2(e1, e2)
2780 }
2781 return
2782 }
2783
2784
2785 func get_MountAddr() *(func(source string, target string, fstype string, flags uintptr, data string) (err error))
2786
2787 var Mount = enter_Mount
2788
2789 func enter_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2790 funcref := get_MountAddr()
2791 if validMount() {
2792 *funcref = impl_Mount
2793 } else {
2794 *funcref = legacyMount
2795 }
2796 return (*funcref)(source, target, fstype, flags, data)
2797 }
2798
2799 func legacyMount(source string, target string, fstype string, flags uintptr, data string) (err error) {
2800 if needspace := 8 - len(fstype); needspace <= 0 {
2801 fstype = fstype[0:8]
2802 } else {
2803 fstype += " "[0:needspace]
2804 }
2805 return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
2806 }
2807
2808 func validMount() bool {
2809 if funcptrtest(GetZosLibVec()+SYS___MOUNT1_A<<4, "") == 0 {
2810 if name, err := getLeFuncName(GetZosLibVec() + SYS___MOUNT1_A<<4); err == nil {
2811 return name == "__mount1_a"
2812 }
2813 }
2814 return false
2815 }
2816
2817
2818
2819
2820 func impl_Unmount(target string, flags int) (err error) {
2821 var _p0 *byte
2822 _p0, err = BytePtrFromString(target)
2823 if err != nil {
2824 return
2825 }
2826 runtime.EnterSyscall()
2827 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UMOUNT2_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(flags))
2828 runtime.ExitSyscall()
2829 if int64(r0) == -1 {
2830 err = errnoErr2(e1, e2)
2831 }
2832 return
2833 }
2834
2835
2836 func get_UnmountAddr() *(func(target string, flags int) (err error))
2837
2838 var Unmount = enter_Unmount
2839
2840 func enter_Unmount(target string, flags int) (err error) {
2841 funcref := get_UnmountAddr()
2842 if funcptrtest(GetZosLibVec()+SYS___UMOUNT2_A<<4, "") == 0 {
2843 *funcref = impl_Unmount
2844 } else {
2845 *funcref = legacyUnmount
2846 }
2847 return (*funcref)(target, flags)
2848 }
2849
2850 func legacyUnmount(name string, mtm int) (err error) {
2851
2852
2853 if name[0] != '/' {
2854 return unmount_LE(name, mtm)
2855 }
2856
2857 b2s := func(arr []byte) string {
2858 var str string
2859 for i := 0; i < len(arr); i++ {
2860 if arr[i] == 0 {
2861 str = string(arr[:i])
2862 break
2863 }
2864 }
2865 return str
2866 }
2867 var buffer struct {
2868 header W_Mnth
2869 fsinfo [64]W_Mntent
2870 }
2871 fs_count, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
2872 if err == nil {
2873 err = EINVAL
2874 for i := 0; i < fs_count; i++ {
2875 if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
2876 err = unmount_LE(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
2877 break
2878 }
2879 }
2880 } else if fs_count == 0 {
2881 err = EINVAL
2882 }
2883 return err
2884 }
2885
2886
2887
2888 func direntIno(buf []byte) (uint64, bool) {
2889 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
2890 }
2891
2892 func direntReclen(buf []byte) (uint64, bool) {
2893 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
2894 }
2895
2896 func direntNamlen(buf []byte) (uint64, bool) {
2897 reclen, ok := direntReclen(buf)
2898 if !ok {
2899 return 0, false
2900 }
2901 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
2902 }
2903
2904 func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
2905 var d Dirent
2906
2907 d.Ino = uint64(dirent.Ino)
2908 offset, err := Telldir(dir)
2909 if err != nil {
2910 return d, err
2911 }
2912
2913 d.Off = int64(offset)
2914 s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
2915 copy(d.Name[:], s)
2916
2917 d.Reclen = uint16(24 + len(d.NameString()))
2918 var st Stat_t
2919 path = path + "/" + s
2920 err = Lstat(path, &st)
2921 if err != nil {
2922 return d, err
2923 }
2924
2925 d.Type = uint8(st.Mode >> 24)
2926 return d, err
2927 }
2928
2929 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
2930
2931
2932
2933
2934
2935
2936
2937 skip, err := Seek(fd, 0, 1 )
2938 if err != nil {
2939 return 0, err
2940 }
2941
2942
2943 path, err := ZosFdToPath(fd)
2944 if err != nil {
2945 return 0, err
2946 }
2947 d, err := Opendir(path)
2948 if err != nil {
2949 return 0, err
2950 }
2951 defer Closedir(d)
2952
2953 var cnt int64
2954 for {
2955 var entryLE direntLE
2956 var entrypLE *direntLE
2957 e := Readdir_r(d, &entryLE, &entrypLE)
2958 if e != nil {
2959 return n, e
2960 }
2961 if entrypLE == nil {
2962 break
2963 }
2964 if skip > 0 {
2965 skip--
2966 cnt++
2967 continue
2968 }
2969
2970
2971 entry, e := direntLeToDirentUnix(&entryLE, d, path)
2972 if e != nil {
2973 return n, e
2974 }
2975
2976 reclen := int(entry.Reclen)
2977 if reclen > len(buf) {
2978
2979
2980
2981
2982 break
2983 }
2984
2985
2986 s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
2987 copy(buf, s)
2988
2989 buf = buf[reclen:]
2990 n += reclen
2991 cnt++
2992 }
2993
2994
2995 _, err = Seek(fd, cnt, 0 )
2996 if err != nil {
2997 return n, err
2998 }
2999
3000 return n, nil
3001 }
3002
3003 func Err2ad() (eadd *int) {
3004 r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERR2AD<<4)
3005 eadd = (*int)(unsafe.Pointer(r0))
3006 return
3007 }
3008
3009 func ZosConsolePrintf(format string, v ...interface{}) (int, error) {
3010 type __cmsg struct {
3011 _ uint16
3012 _ [2]uint8
3013 __msg_length uint32
3014 __msg uintptr
3015 _ [4]uint8
3016 }
3017 msg := fmt.Sprintf(format, v...)
3018 strptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&msg)).Data)
3019 len := (*reflect.StringHeader)(unsafe.Pointer(&msg)).Len
3020 cmsg := __cmsg{__msg_length: uint32(len), __msg: uintptr(strptr)}
3021 cmd := uint32(0)
3022 runtime.EnterSyscall()
3023 rc, err2, err1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____CONSOLE_A<<4, uintptr(unsafe.Pointer(&cmsg)), 0, uintptr(unsafe.Pointer(&cmd)))
3024 runtime.ExitSyscall()
3025 if rc != 0 {
3026 return 0, fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
3027 }
3028 return 0, nil
3029 }
3030 func ZosStringToEbcdicBytes(str string, nullterm bool) (ebcdicBytes []byte) {
3031 if nullterm {
3032 ebcdicBytes = []byte(str + "\x00")
3033 } else {
3034 ebcdicBytes = []byte(str)
3035 }
3036 A2e(ebcdicBytes)
3037 return
3038 }
3039 func ZosEbcdicBytesToString(b []byte, trimRight bool) (str string) {
3040 res := make([]byte, len(b))
3041 copy(res, b)
3042 E2a(res)
3043 if trimRight {
3044 str = string(bytes.TrimRight(res, " \x00"))
3045 } else {
3046 str = string(res)
3047 }
3048 return
3049 }
3050
3051 func fdToPath(dirfd int) (path string, err error) {
3052 var buffer [1024]byte
3053
3054 ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
3055 []uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
3056 if ret == 0 {
3057 zb := bytes.IndexByte(buffer[:], 0)
3058 if zb == -1 {
3059 zb = len(buffer)
3060 }
3061
3062 runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
3063 []uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
3064 return string(buffer[:zb]), nil
3065 }
3066
3067 errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
3068 []uintptr{}))))
3069
3070 errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
3071 []uintptr{}))
3072
3073 ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
3074 []uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
3075 if ret == 0 {
3076 zb := bytes.IndexByte(buffer[:], 0)
3077 if zb == -1 {
3078 zb = len(buffer)
3079 }
3080 return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
3081 } else {
3082 return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
3083 }
3084 }
3085
3086 func impl_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3087 var _p0 *byte
3088 _p0, err = BytePtrFromString(path)
3089 if err != nil {
3090 return
3091 }
3092 runtime.EnterSyscall()
3093 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFOAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
3094 runtime.ExitSyscall()
3095 if int64(r0) == -1 {
3096 err = errnoErr2(e1, e2)
3097 }
3098 return
3099 }
3100
3101
3102 func get_MkfifoatAddr() *(func(dirfd int, path string, mode uint32) (err error))
3103
3104 var Mkfifoat = enter_Mkfifoat
3105
3106 func enter_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3107 funcref := get_MkfifoatAddr()
3108 if funcptrtest(GetZosLibVec()+SYS___MKFIFOAT_A<<4, "") == 0 {
3109 *funcref = impl_Mkfifoat
3110 } else {
3111 *funcref = legacy_Mkfifoat
3112 }
3113 return (*funcref)(dirfd, path, mode)
3114 }
3115
3116 func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
3117 dirname, err := ZosFdToPath(dirfd)
3118 if err != nil {
3119 return err
3120 }
3121 return Mkfifo(dirname+"/"+path, mode)
3122 }
3123
3124
3125
3126
3127
3128 func fcntlAsIs(fd uintptr, cmd int, arg uintptr) (val int, err error) {
3129 runtime.EnterSyscall()
3130 r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), arg)
3131 runtime.ExitSyscall()
3132 val = int(r0)
3133 if int64(r0) == -1 {
3134 err = errnoErr2(e1, e2)
3135 }
3136 return
3137 }
3138
3139 func Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) {
3140 switch op.(type) {
3141 case *Flock_t:
3142 err = FcntlFlock(fd, cmd, op.(*Flock_t))
3143 if err != nil {
3144 ret = -1
3145 }
3146 return
3147 case int:
3148 return FcntlInt(fd, cmd, op.(int))
3149 case *F_cnvrt:
3150 return fcntlAsIs(fd, cmd, uintptr(unsafe.Pointer(op.(*F_cnvrt))))
3151 case unsafe.Pointer:
3152 return fcntlAsIs(fd, cmd, uintptr(op.(unsafe.Pointer)))
3153 default:
3154 return -1, EINVAL
3155 }
3156 return
3157 }
3158
3159 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
3160 if raceenabled {
3161 raceReleaseMerge(unsafe.Pointer(&ioSync))
3162 }
3163 return sendfile(outfd, infd, offset, count)
3164 }
3165
3166 func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
3167
3168 originalOffset, err := Seek(infd, 0, SEEK_CUR)
3169 if err != nil {
3170 return -1, err
3171 }
3172
3173 if offset != nil {
3174 _, err := Seek(infd, *offset, SEEK_SET)
3175 if err != nil {
3176 return -1, err
3177 }
3178 }
3179
3180 buf := make([]byte, count)
3181 readBuf := make([]byte, 0)
3182 var n int = 0
3183 for i := 0; i < count; i += n {
3184 n, err := Read(infd, buf)
3185 if n == 0 {
3186 if err != nil {
3187 return -1, err
3188 } else {
3189 break
3190 }
3191 }
3192 readBuf = append(readBuf, buf...)
3193 buf = buf[0:0]
3194 }
3195
3196 n2, err := Write(outfd, readBuf)
3197 if err != nil {
3198 return -1, err
3199 }
3200
3201
3202
3203 if offset != nil {
3204 *offset = *offset + int64(n)
3205
3206
3207 _, err := Seek(infd, originalOffset, SEEK_SET)
3208 if err != nil {
3209 return -1, err
3210 }
3211 }
3212 return n2, nil
3213 }
3214
View as plain text