Source file src/syscall/syscall_aix.go
1
2
3
4
5
6
7
8
9
10
11
12 package syscall
13
14 import (
15 "unsafe"
16 )
17
18
19 func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
20 func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
21
22
23 const (
24 _ = iota
25 TIOCSCTTY
26 F_DUPFD_CLOEXEC
27 SYS_EXECVE
28 SYS_FCNTL
29 )
30
31 const (
32
33 AF_LOCAL = AF_UNIX
34 )
35
36 func (ts *StTimespec_t) Unix() (sec int64, nsec int64) {
37 return int64(ts.Sec), int64(ts.Nsec)
38 }
39
40 func (ts *StTimespec_t) Nano() int64 {
41 return int64(ts.Sec)*1e9 + int64(ts.Nsec)
42 }
43
44
47
48
49
50
51
52
53
54
55
56
57 func Pipe(p []int) (err error) {
58 if len(p) != 2 {
59 return EINVAL
60 }
61 var pp [2]_C_int
62 err = pipe(&pp)
63 p[0] = int(pp[0])
64 p[1] = int(pp[1])
65 return
66 }
67
68
69 func Readlink(path string, buf []byte) (n int, err error) {
70 s := uint64(len(buf))
71 return readlink(path, buf, s)
72 }
73
74
75 func Utimes(path string, tv []Timeval) error {
76 if len(tv) != 2 {
77 return EINVAL
78 }
79 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
80 }
81
82
83 func UtimesNano(path string, ts []Timespec) error {
84 if len(ts) != 2 {
85 return EINVAL
86 }
87 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
88 }
89
90
91 func Unlinkat(dirfd int, path string) (err error) {
92 return unlinkat(dirfd, path, 0)
93 }
94
95
96
97 const ImplementsGetwd = true
98
99 func Getwd() (ret string, err error) {
100 for len := uint64(4096); ; len *= 2 {
101 b := make([]byte, len)
102 err := getcwd(&b[0], len)
103 if err == nil {
104 i := 0
105 for b[i] != 0 {
106 i++
107 }
108 return string(b[0:i]), nil
109 }
110 if err != ERANGE {
111 return "", err
112 }
113 }
114 }
115
116 func Getcwd(buf []byte) (n int, err error) {
117 err = getcwd(&buf[0], uint64(len(buf)))
118 if err == nil {
119 i := 0
120 for buf[i] != 0 {
121 i++
122 }
123 n = i + 1
124 }
125 return
126 }
127
128
129
130
131 func Getgroups() (gids []int, err error) {
132 n, err := getgroups(0, nil)
133 if err != nil {
134 return nil, err
135 }
136 if n == 0 {
137 return nil, nil
138 }
139
140
141 if n < 0 || n > 1000 {
142 return nil, EINVAL
143 }
144
145 a := make([]_Gid_t, n)
146 n, err = getgroups(n, &a[0])
147 if err != nil {
148 return nil, err
149 }
150 gids = make([]int, n)
151 for i, v := range a[0:n] {
152 gids[i] = int(v)
153 }
154 return
155 }
156
157 func Setgroups(gids []int) (err error) {
158 if len(gids) == 0 {
159 return setgroups(0, nil)
160 }
161
162 a := make([]_Gid_t, len(gids))
163 for i, v := range gids {
164 a[i] = _Gid_t(v)
165 }
166 return setgroups(len(a), &a[0])
167 }
168
169 func direntIno(buf []byte) (uint64, bool) {
170 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
171 }
172
173 func direntReclen(buf []byte) (uint64, bool) {
174 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
175 }
176
177 func direntNamlen(buf []byte) (uint64, bool) {
178 reclen, ok := direntReclen(buf)
179 if !ok {
180 return 0, false
181 }
182 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
183 }
184
185 func Gettimeofday(tv *Timeval) (err error) {
186 err = gettimeofday(tv, nil)
187 return
188 }
189
190
191 func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
192 return -1, ENOSYS
193 }
194
195
196 func ReadDirent(fd int, buf []byte) (n int, err error) {
197 return getdirent(fd, buf)
198 }
199
200
201 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
202 var status _C_int
203 var r _Pid_t
204 err = ERESTART
205
206
207 for err == ERESTART {
208 r, err = wait4(_Pid_t(pid), &status, options, rusage)
209 }
210 wpid = int(r)
211 if wstatus != nil {
212 *wstatus = WaitStatus(status)
213 }
214 return
215 }
216
217
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
240 if sa.Port < 0 || sa.Port > 0xFFFF {
241 return nil, 0, EINVAL
242 }
243 sa.raw.Family = AF_INET
244 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
245 p[0] = byte(sa.Port >> 8)
246 p[1] = byte(sa.Port)
247 for i := 0; i < len(sa.Addr); i++ {
248 sa.raw.Addr[i] = sa.Addr[i]
249 }
250 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
251 }
252
253 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
254 if sa.Port < 0 || sa.Port > 0xFFFF {
255 return nil, 0, EINVAL
256 }
257 sa.raw.Family = AF_INET6
258 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
259 p[0] = byte(sa.Port >> 8)
260 p[1] = byte(sa.Port)
261 sa.raw.Scope_id = sa.ZoneId
262 for i := 0; i < len(sa.Addr); i++ {
263 sa.raw.Addr[i] = sa.Addr[i]
264 }
265 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
266 }
267
268 func (sa *RawSockaddrUnix) setLen(n int) {
269 sa.Len = uint8(3 + n)
270 }
271
272 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
273 name := sa.Name
274 n := len(name)
275 if n > len(sa.raw.Path) {
276 return nil, 0, EINVAL
277 }
278 sa.raw.Family = AF_UNIX
279 sa.raw.setLen(n)
280 for i := 0; i < n; i++ {
281 sa.raw.Path[i] = uint8(name[i])
282 }
283
284 sl := _Socklen(2)
285 if n > 0 {
286 sl += _Socklen(n) + 1
287 }
288
289 return unsafe.Pointer(&sa.raw), sl, nil
290 }
291
292 func Getsockname(fd int) (sa Sockaddr, err error) {
293 var rsa RawSockaddrAny
294 var len _Socklen = SizeofSockaddrAny
295 if err = getsockname(fd, &rsa, &len); err != nil {
296 return
297 }
298 return anyToSockaddr(&rsa)
299 }
300
301
302 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
303 var rsa RawSockaddrAny
304 var len _Socklen = SizeofSockaddrAny
305 nfd, err = accept(fd, &rsa, &len)
306 if err != nil {
307 return
308 }
309 sa, err = anyToSockaddr(&rsa)
310 if err != nil {
311 Close(nfd)
312 nfd = 0
313 }
314 return
315 }
316
317 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
318 var msg Msghdr
319 var rsa RawSockaddrAny
320 msg.Name = (*byte)(unsafe.Pointer(&rsa))
321 msg.Namelen = uint32(SizeofSockaddrAny)
322 var iov Iovec
323 if len(p) > 0 {
324 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
325 iov.SetLen(len(p))
326 }
327 var dummy byte
328 if len(oob) > 0 {
329 var sockType int
330 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
331 if err != nil {
332 return
333 }
334
335 if sockType != SOCK_DGRAM && len(p) == 0 {
336 iov.Base = &dummy
337 iov.SetLen(1)
338 }
339 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
340 msg.SetControllen(len(oob))
341 }
342 msg.Iov = &iov
343 msg.Iovlen = 1
344 if n, err = recvmsg(fd, &msg, flags); err != nil {
345 return
346 }
347 oobn = int(msg.Controllen)
348 recvflags = int(msg.Flags)
349
350 if rsa.Addr.Family != AF_UNSPEC {
351 from, err = anyToSockaddr(&rsa)
352 }
353 return
354 }
355
356 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
357 _, err = SendmsgN(fd, p, oob, to, flags)
358 return
359 }
360
361 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
362 var ptr unsafe.Pointer
363 var salen _Socklen
364 if to != nil {
365 ptr, salen, err = to.sockaddr()
366 if err != nil {
367 return 0, err
368 }
369 }
370 var msg Msghdr
371 msg.Name = (*byte)(unsafe.Pointer(ptr))
372 msg.Namelen = uint32(salen)
373 var iov Iovec
374 if len(p) > 0 {
375 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
376 iov.SetLen(len(p))
377 }
378 var dummy byte
379 if len(oob) > 0 {
380 var sockType int
381 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
382 if err != nil {
383 return 0, err
384 }
385
386 if sockType != SOCK_DGRAM && len(p) == 0 {
387 iov.Base = &dummy
388 iov.SetLen(1)
389 }
390 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
391 msg.SetControllen(len(oob))
392 }
393 msg.Iov = &iov
394 msg.Iovlen = 1
395 if n, err = sendmsg(fd, &msg, flags); err != nil {
396 return 0, err
397 }
398 if len(oob) > 0 && len(p) == 0 {
399 n = 0
400 }
401 return n, nil
402 }
403
404 func (sa *RawSockaddrUnix) getLen() (int, error) {
405
406
407 n := SizeofSockaddrUnix - 3
408 for i := 0; i < n; i++ {
409 if sa.Path[i] == 0 {
410 n = i
411 break
412 }
413 }
414 return n, nil
415 }
416
417 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
418 switch rsa.Addr.Family {
419 case AF_UNIX:
420 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
421 sa := new(SockaddrUnix)
422 n, err := pp.getLen()
423 if err != nil {
424 return nil, err
425 }
426 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))
427 sa.Name = string(bytes[0:n])
428 return sa, nil
429
430 case AF_INET:
431 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
432 sa := new(SockaddrInet4)
433 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
434 sa.Port = int(p[0])<<8 + int(p[1])
435 for i := 0; i < len(sa.Addr); i++ {
436 sa.Addr[i] = pp.Addr[i]
437 }
438 return sa, nil
439
440 case AF_INET6:
441 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
442 sa := new(SockaddrInet6)
443 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
444 sa.Port = int(p[0])<<8 + int(p[1])
445 for i := 0; i < len(sa.Addr); i++ {
446 sa.Addr[i] = pp.Addr[i]
447 }
448 return sa, nil
449 }
450 return nil, EAFNOSUPPORT
451 }
452
453 type SockaddrDatalink struct {
454 Len uint8
455 Family uint8
456 Index uint16
457 Type uint8
458 Nlen uint8
459 Alen uint8
460 Slen uint8
461 Data [120]uint8
462 raw RawSockaddrDatalink
463 }
464
465
468
469 type WaitStatus uint32
470
471 func (w WaitStatus) Stopped() bool { return w&0x40 != 0 }
472 func (w WaitStatus) StopSignal() Signal {
473 if !w.Stopped() {
474 return -1
475 }
476 return Signal(w>>8) & 0xFF
477 }
478
479 func (w WaitStatus) Exited() bool { return w&0xFF == 0 }
480 func (w WaitStatus) ExitStatus() int {
481 if !w.Exited() {
482 return -1
483 }
484 return int((w >> 8) & 0xFF)
485 }
486
487 func (w WaitStatus) Signaled() bool { return w&0x40 == 0 && w&0xFF != 0 }
488 func (w WaitStatus) Signal() Signal {
489 if !w.Signaled() {
490 return -1
491 }
492 return Signal(w>>16) & 0xFF
493 }
494
495 func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 }
496
497 func (w WaitStatus) CoreDump() bool { return w&0x200 == 0 }
498
499 func (w WaitStatus) TrapCause() int { return -1 }
500
501
504
505
506
507
508 func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno {
509 if request == PTRACE_TRACEME {
510
511 err := ptrace64(PT_TRACE_ME, 0, 0, 0, 0)
512 if err != nil {
513 return err.(Errno)
514 }
515 return 0
516 }
517 return ENOSYS
518 }
519
520 func ptracePeek(pid int, addr uintptr, out []byte) (count int, err error) {
521 n := 0
522 for len(out) > 0 {
523 bsize := len(out)
524 if bsize > 1024 {
525 bsize = 1024
526 }
527 err = ptrace64(PT_READ_BLOCK, int64(pid), int64(addr), bsize, uintptr(unsafe.Pointer(&out[0])))
528 if err != nil {
529 return 0, err
530 }
531 addr += uintptr(bsize)
532 n += bsize
533 out = out[n:]
534 }
535 return n, nil
536 }
537
538 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
539 return ptracePeek(pid, addr, out)
540 }
541
542 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
543 return ptracePeek(pid, addr, out)
544 }
545
546 func ptracePoke(pid int, addr uintptr, data []byte) (count int, err error) {
547 n := 0
548 for len(data) > 0 {
549 bsize := len(data)
550 if bsize > 1024 {
551 bsize = 1024
552 }
553 err = ptrace64(PT_WRITE_BLOCK, int64(pid), int64(addr), bsize, uintptr(unsafe.Pointer(&data[0])))
554 if err != nil {
555 return 0, err
556 }
557 addr += uintptr(bsize)
558 n += bsize
559 data = data[n:]
560 }
561 return n, nil
562 }
563
564 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
565 return ptracePoke(pid, addr, data)
566 }
567
568 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
569 return ptracePoke(pid, addr, data)
570 }
571
572 func PtraceCont(pid int, signal int) (err error) {
573 return ptrace64(PT_CONTINUE, int64(pid), 1, signal, 0)
574 }
575
576 func PtraceSingleStep(pid int) (err error) { return ptrace64(PT_STEP, int64(pid), 1, 0, 0) }
577
578 func PtraceAttach(pid int) (err error) { return ptrace64(PT_ATTACH, int64(pid), 0, 0, 0) }
579
580 func PtraceDetach(pid int) (err error) { return ptrace64(PT_DETACH, int64(pid), 0, 0, 0) }
581
582
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647 func setTimespec(sec, nsec int64) Timespec {
648 return Timespec{Sec: sec, Nsec: nsec}
649 }
650
651 func setTimeval(sec, usec int64) Timeval {
652 return Timeval{Sec: sec, Usec: int32(usec)}
653 }
654
655 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
656 r0, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
657 n = int(r0)
658 if e1 != 0 {
659 err = e1
660 }
661 return
662 }
663
664
667
668 var mapper = &mmapper{
669 active: make(map[*byte][]byte),
670 mmap: mmap,
671 munmap: munmap,
672 }
673
674
675
676
677 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
678 return mapper.Mmap(fd, offset, length, prot, flags)
679 }
680
681 func Munmap(b []byte) (err error) {
682 return mapper.Munmap(b)
683 }
684
View as plain text