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