1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
6 // This file is compiled as ordinary Go code,
7 // but it is also input to mksyscall,
8 // which parses the //sys lines and generates system call stubs.
9 // Note that sometimes we use a lowercase //sys name and
10 // wrap it in our own nicer implementation.
18 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
19 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
20 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
21 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
23 // Implemented in runtime/syscall_aix.go.
24 func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
25 func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
27 // Constant expected by package but not supported
37 // AF_LOCAL doesn't exist on AIX
43 func (ts *StTimespec_t) Unix() (sec int64, nsec int64) {
44 return int64(ts.Sec), int64(ts.Nsec)
47 func (ts *StTimespec_t) Nano() int64 {
48 return int64(ts.Sec)*1e9 + int64(ts.Nsec)
55 func Access(path string, mode uint32) (err error) {
56 return Faccessat(_AT_FDCWD, path, mode, 0)
59 // fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX
60 // There is no way to create a custom fcntl and to keep //sys fcntl easily,
61 // because we need fcntl name for its libc symbol. This is linked with the script.
62 // But, as fcntl is currently not exported and isn't called with F_DUP2FD,
64 //sys fcntl(fd int, cmd int, arg int) (val int, err error)
65 //sys Dup2(old int, new int) (err error)
67 //sysnb pipe(p *[2]_C_int) (err error)
69 func Pipe(p []int) (err error) {
82 //sys readlink(path string, buf []byte, bufSize uint64) (n int, err error)
84 func Readlink(path string, buf []byte) (n int, err error) {
86 return readlink(path, buf, s)
89 //sys utimes(path string, times *[2]Timeval) (err error)
91 func Utimes(path string, tv []Timeval) error {
95 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
98 //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
100 func UtimesNano(path string, ts []Timespec) error {
104 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
107 //sys unlinkat(dirfd int, path string, flags int) (err error)
109 func Unlinkat(dirfd int, path string) (err error) {
110 return unlinkat(dirfd, path, 0)
113 //sys getcwd(buf *byte, size uint64) (err error)
115 const ImplementsGetwd = true
117 func Getwd() (ret string, err error) {
118 for len := uint64(4096); ; len *= 2 {
119 b := make([]byte, len)
120 err := getcwd(&b[0], len)
126 return string(b[0:i]), nil
134 func Getcwd(buf []byte) (n int, err error) {
135 err = getcwd(&buf[0], uint64(len(buf)))
146 //sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error)
147 //sysnb setgroups(ngid int, gid *_Gid_t) (err error)
149 func Getgroups() (gids []int, err error) {
150 n, err := getgroups(0, nil)
158 // Sanity check group count. Max is 16 on BSD.
159 if n < 0 || n > 1000 {
163 a := make([]_Gid_t, n)
164 n, err = getgroups(n, &a[0])
168 gids = make([]int, n)
169 for i, v := range a[0:n] {
175 func Setgroups(gids []int) (err error) {
177 return setgroups(0, nil)
180 a := make([]_Gid_t, len(gids))
181 for i, v := range gids {
184 return setgroups(len(a), &a[0])
187 func direntIno(buf []byte) (uint64, bool) {
188 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
191 func direntReclen(buf []byte) (uint64, bool) {
192 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
195 func direntNamlen(buf []byte) (uint64, bool) {
196 reclen, ok := direntReclen(buf)
200 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
203 func Gettimeofday(tv *Timeval) (err error) {
204 err = gettimeofday(tv, nil)
209 func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
213 //sys getdirent(fd int, buf []byte) (n int, err error)
215 func ReadDirent(fd int, buf []byte) (n int, err error) {
216 return getdirent(fd, buf)
219 //sys wait4(pid _Pid_t, status *_C_int, options int, rusage *Rusage) (wpid _Pid_t, err error)
221 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
225 // AIX wait4 may return with ERESTART errno, while the processus is still
227 for err == ERESTART {
228 r, err = wait4(_Pid_t(pid), &status, options, rusage)
232 *wstatus = WaitStatus(status)
237 //sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range
239 func Fsync(fd int) error {
240 return fsyncRange(fd, O_SYNC, 0, 0)
246 //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
247 //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
248 //sys Getkerninfo(op int32, where uintptr, size uintptr, arg int64) (i int32, err error)
249 //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
250 //sys Listen(s int, backlog int) (err error)
251 //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
252 //sys socket(domain int, typ int, proto int) (fd int, err error)
253 //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
254 //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
255 //sys getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
256 //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
257 //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
258 //sys Shutdown(s int, how int) (err error)
260 // In order to use msghdr structure with Control, Controllen in golang.org/x/net,
261 // nrecvmsg and nsendmsg must be used.
262 //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = nrecvmsg
263 //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg
265 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
266 if sa.Port < 0 || sa.Port > 0xFFFF {
267 return nil, 0, EINVAL
269 sa.raw.Family = AF_INET
270 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
271 p[0] = byte(sa.Port >> 8)
273 sa.raw.Addr = sa.Addr
274 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
277 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
278 if sa.Port < 0 || sa.Port > 0xFFFF {
279 return nil, 0, EINVAL
281 sa.raw.Family = AF_INET6
282 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
283 p[0] = byte(sa.Port >> 8)
285 sa.raw.Scope_id = sa.ZoneId
286 sa.raw.Addr = sa.Addr
287 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
290 func (sa *RawSockaddrUnix) setLen(n int) {
291 sa.Len = uint8(3 + n) // 2 for Family, Len; 1 for NUL.
294 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
297 if n > len(sa.raw.Path) {
298 return nil, 0, EINVAL
300 sa.raw.Family = AF_UNIX
302 for i := 0; i < n; i++ {
303 sa.raw.Path[i] = uint8(name[i])
305 // length is family (uint16), name, NUL.
308 sl += _Socklen(n) + 1
311 return unsafe.Pointer(&sa.raw), sl, nil
314 func Getsockname(fd int) (sa Sockaddr, err error) {
315 var rsa RawSockaddrAny
316 var len _Socklen = SizeofSockaddrAny
317 if err = getsockname(fd, &rsa, &len); err != nil {
320 return anyToSockaddr(&rsa)
323 //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
325 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
326 var rsa RawSockaddrAny
327 var len _Socklen = SizeofSockaddrAny
328 nfd, err = accept(fd, &rsa, &len)
332 sa, err = anyToSockaddr(&rsa)
340 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
342 msg.Name = (*byte)(unsafe.Pointer(rsa))
343 msg.Namelen = uint32(SizeofSockaddrAny)
352 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
356 // receive at least one normal byte
357 if sockType != SOCK_DGRAM && len(p) == 0 {
361 msg.Control = &oob[0]
362 msg.SetControllen(len(oob))
366 if n, err = recvmsg(fd, &msg, flags); err != nil {
369 oobn = int(msg.Controllen)
370 recvflags = int(msg.Flags)
374 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
376 msg.Name = (*byte)(ptr)
377 msg.Namelen = uint32(salen)
386 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
390 // send at least one normal byte
391 if sockType != SOCK_DGRAM && len(p) == 0 {
395 msg.Control = &oob[0]
396 msg.SetControllen(len(oob))
400 if n, err = sendmsg(fd, &msg, flags); err != nil {
403 if len(oob) > 0 && len(p) == 0 {
409 func (sa *RawSockaddrUnix) getLen() (int, error) {
410 // Some versions of AIX have a bug in getsockname (see IV78655).
411 // We can't rely on sa.Len being set correctly.
412 n := SizeofSockaddrUnix - 3 // subtract leading Family, Len, terminating NUL.
413 for i := 0; i < n; i++ {
422 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
423 switch rsa.Addr.Family {
425 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
426 sa := new(SockaddrUnix)
427 n, err := pp.getLen()
431 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
435 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
436 sa := new(SockaddrInet4)
437 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
438 sa.Port = int(p[0])<<8 + int(p[1])
443 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
444 sa := new(SockaddrInet6)
445 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
446 sa.Port = int(p[0])<<8 + int(p[1])
450 return nil, EAFNOSUPPORT
453 type SockaddrDatalink struct {
462 raw RawSockaddrDatalink
469 type WaitStatus uint32
471 func (w WaitStatus) Stopped() bool { return w&0x40 != 0 }
472 func (w WaitStatus) StopSignal() Signal {
476 return Signal(w>>8) & 0xFF
479 func (w WaitStatus) Exited() bool { return w&0xFF == 0 }
480 func (w WaitStatus) ExitStatus() int {
484 return int((w >> 8) & 0xFF)
487 func (w WaitStatus) Signaled() bool { return w&0x40 == 0 && w&0xFF != 0 }
488 func (w WaitStatus) Signal() Signal {
492 return Signal(w>>16) & 0xFF
495 func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 }
497 func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 }
499 func (w WaitStatus) TrapCause() int { return -1 }
505 //sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
506 //sys ptrace64(request int, id int64, addr int64, data int, buff uintptr) (err error)
507 //sys ptrace64Ptr(request int, id int64, addr int64, data int, buff unsafe.Pointer) (err error) = ptrace64
509 func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno {
510 if request == PTRACE_TRACEME {
511 // Convert to AIX ptrace call.
512 err := ptrace64(PT_TRACE_ME, 0, 0, 0, 0)
521 func ptracePeek(pid int, addr uintptr, out []byte) (count int, err error) {
528 err = ptrace64Ptr(PT_READ_BLOCK, int64(pid), int64(addr), bsize, unsafe.Pointer(&out[0]))
532 addr += uintptr(bsize)
539 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
540 return ptracePeek(pid, addr, out)
543 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
544 return ptracePeek(pid, addr, out)
547 func ptracePoke(pid int, addr uintptr, data []byte) (count int, err error) {
554 err = ptrace64Ptr(PT_WRITE_BLOCK, int64(pid), int64(addr), bsize, unsafe.Pointer(&data[0]))
558 addr += uintptr(bsize)
565 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
566 return ptracePoke(pid, addr, data)
569 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
570 return ptracePoke(pid, addr, data)
573 func PtraceCont(pid int, signal int) (err error) {
574 return ptrace64(PT_CONTINUE, int64(pid), 1, signal, 0)
577 func PtraceSingleStep(pid int) (err error) { return ptrace64(PT_STEP, int64(pid), 1, 0, 0) }
579 func PtraceAttach(pid int) (err error) { return ptrace64(PT_ATTACH, int64(pid), 0, 0, 0) }
581 func PtraceDetach(pid int) (err error) { return ptrace64(PT_DETACH, int64(pid), 0, 0, 0) }
587 //sys Acct(path string) (err error)
588 //sys Chdir(path string) (err error)
589 //sys Chmod(path string, mode uint32) (err error)
590 //sys Chown(path string, uid int, gid int) (err error)
591 //sys Chroot(path string) (err error)
592 //sys Close(fd int) (err error)
593 //sys Dup(fd int) (nfd int, err error)
594 //sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
595 //sys Fchdir(fd int) (err error)
596 //sys Fchmod(fd int, mode uint32) (err error)
597 //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
598 //sys Fchown(fd int, uid int, gid int) (err error)
599 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
600 //sys Fpathconf(fd int, name int) (val int, err error)
601 //sys Fstat(fd int, stat *Stat_t) (err error)
602 //sys Fstatfs(fd int, buf *Statfs_t) (err error)
603 //sys Ftruncate(fd int, length int64) (err error)
604 //sysnb Getgid() (gid int)
605 //sysnb Getpid() (pid int)
606 //sys Geteuid() (euid int)
607 //sys Getegid() (egid int)
608 //sys Getppid() (ppid int)
609 //sys Getpriority(which int, who int) (n int, err error)
610 //sysnb Getrlimit(which int, lim *Rlimit) (err error)
611 //sysnb Getrusage(who int, rusage *Rusage) (err error)
612 //sysnb Getuid() (uid int)
613 //sys Kill(pid int, signum Signal) (err error)
614 //sys Lchown(path string, uid int, gid int) (err error)
615 //sys Link(path string, link string) (err error)
616 //sys Lstat(path string, stat *Stat_t) (err error)
617 //sys Mkdir(path string, mode uint32) (err error)
618 //sys Mkdirat(dirfd int, path string, mode uint32) (err error)
619 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
620 //sys Open(path string, mode int, perm uint32) (fd int, err error)
621 //sys pread(fd int, p []byte, offset int64) (n int, err error)
622 //sys pwrite(fd int, p []byte, offset int64) (n int, err error)
623 //sys read(fd int, p []byte) (n int, err error)
624 //sys Reboot(how int) (err error)
625 //sys Rename(from string, to string) (err error)
626 //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
627 //sys Rmdir(path string) (err error)
628 //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
629 //sysnb Setegid(egid int) (err error)
630 //sysnb Seteuid(euid int) (err error)
631 //sysnb Setgid(gid int) (err error)
632 //sysnb Setpgid(pid int, pgid int) (err error)
633 //sys Setpriority(which int, who int, prio int) (err error)
634 //sysnb Setregid(rgid int, egid int) (err error)
635 //sysnb Setreuid(ruid int, euid int) (err error)
636 //sysnb setrlimit(which int, lim *Rlimit) (err error)
637 //sys Stat(path string, stat *Stat_t) (err error)
638 //sys Statfs(path string, buf *Statfs_t) (err error)
639 //sys Symlink(path string, link string) (err error)
640 //sys Truncate(path string, length int64) (err error)
641 //sys Umask(newmask int) (oldmask int)
642 //sys Unlink(path string) (err error)
643 //sysnb Uname(buf *Utsname) (err error)
644 //sys write(fd int, p []byte) (n int, err error)
645 //sys writev(fd int, iovecs []Iovec) (n uintptr, err error)
647 //sys gettimeofday(tv *Timeval, tzp *Timezone) (err error)
649 func setTimespec(sec, nsec int64) Timespec {
650 return Timespec{Sec: sec, Nsec: nsec}
653 func setTimeval(sec, usec int64) Timeval {
654 return Timeval{Sec: sec, Usec: int32(usec)}
657 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
658 r0, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
670 var mapper = &mmapper{
671 active: make(map[*byte][]byte),
676 //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
677 //sys munmap(addr uintptr, length uintptr) (err error)
679 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
680 return mapper.Mmap(fd, offset, length, prot, flags)
683 func Munmap(b []byte) (err error) {
684 return mapper.Munmap(b)