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