syscall_aix.go (15742B)
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. 4 5 //go:build aix 6 // +build aix 7 8 // Aix system calls. 9 // This file is compiled as ordinary Go code, 10 // but it is also input to mksyscall, 11 // which parses the //sys lines and generates system call stubs. 12 // Note that sometimes we use a lowercase //sys name and 13 // wrap it in our own nicer implementation. 14 15 package unix 16 17 import "unsafe" 18 19 /* 20 * Wrapped 21 */ 22 23 func Access(path string, mode uint32) (err error) { 24 return Faccessat(AT_FDCWD, path, mode, 0) 25 } 26 27 func Chmod(path string, mode uint32) (err error) { 28 return Fchmodat(AT_FDCWD, path, mode, 0) 29 } 30 31 func Chown(path string, uid int, gid int) (err error) { 32 return Fchownat(AT_FDCWD, path, uid, gid, 0) 33 } 34 35 func Creat(path string, mode uint32) (fd int, err error) { 36 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) 37 } 38 39 //sys utimes(path string, times *[2]Timeval) (err error) 40 func Utimes(path string, tv []Timeval) error { 41 if len(tv) != 2 { 42 return EINVAL 43 } 44 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 45 } 46 47 //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) 48 func UtimesNano(path string, ts []Timespec) error { 49 if len(ts) != 2 { 50 return EINVAL 51 } 52 return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 53 } 54 55 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { 56 if ts == nil { 57 return utimensat(dirfd, path, nil, flags) 58 } 59 if len(ts) != 2 { 60 return EINVAL 61 } 62 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) 63 } 64 65 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { 66 if sa.Port < 0 || sa.Port > 0xFFFF { 67 return nil, 0, EINVAL 68 } 69 sa.raw.Family = AF_INET 70 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 71 p[0] = byte(sa.Port >> 8) 72 p[1] = byte(sa.Port) 73 sa.raw.Addr = sa.Addr 74 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil 75 } 76 77 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { 78 if sa.Port < 0 || sa.Port > 0xFFFF { 79 return nil, 0, EINVAL 80 } 81 sa.raw.Family = AF_INET6 82 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 83 p[0] = byte(sa.Port >> 8) 84 p[1] = byte(sa.Port) 85 sa.raw.Scope_id = sa.ZoneId 86 sa.raw.Addr = sa.Addr 87 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil 88 } 89 90 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { 91 name := sa.Name 92 n := len(name) 93 if n > len(sa.raw.Path) { 94 return nil, 0, EINVAL 95 } 96 if n == len(sa.raw.Path) && name[0] != '@' { 97 return nil, 0, EINVAL 98 } 99 sa.raw.Family = AF_UNIX 100 for i := 0; i < n; i++ { 101 sa.raw.Path[i] = uint8(name[i]) 102 } 103 // length is family (uint16), name, NUL. 104 sl := _Socklen(2) 105 if n > 0 { 106 sl += _Socklen(n) + 1 107 } 108 if sa.raw.Path[0] == '@' { 109 sa.raw.Path[0] = 0 110 // Don't count trailing NUL for abstract address. 111 sl-- 112 } 113 114 return unsafe.Pointer(&sa.raw), sl, nil 115 } 116 117 func Getsockname(fd int) (sa Sockaddr, err error) { 118 var rsa RawSockaddrAny 119 var len _Socklen = SizeofSockaddrAny 120 if err = getsockname(fd, &rsa, &len); err != nil { 121 return 122 } 123 return anyToSockaddr(fd, &rsa) 124 } 125 126 //sys getcwd(buf []byte) (err error) 127 128 const ImplementsGetwd = true 129 130 func Getwd() (ret string, err error) { 131 for len := uint64(4096); ; len *= 2 { 132 b := make([]byte, len) 133 err := getcwd(b) 134 if err == nil { 135 i := 0 136 for b[i] != 0 { 137 i++ 138 } 139 return string(b[0:i]), nil 140 } 141 if err != ERANGE { 142 return "", err 143 } 144 } 145 } 146 147 func Getcwd(buf []byte) (n int, err error) { 148 err = getcwd(buf) 149 if err == nil { 150 i := 0 151 for buf[i] != 0 { 152 i++ 153 } 154 n = i + 1 155 } 156 return 157 } 158 159 func Getgroups() (gids []int, err error) { 160 n, err := getgroups(0, nil) 161 if err != nil { 162 return nil, err 163 } 164 if n == 0 { 165 return nil, nil 166 } 167 168 // Sanity check group count. Max is 16 on BSD. 169 if n < 0 || n > 1000 { 170 return nil, EINVAL 171 } 172 173 a := make([]_Gid_t, n) 174 n, err = getgroups(n, &a[0]) 175 if err != nil { 176 return nil, err 177 } 178 gids = make([]int, n) 179 for i, v := range a[0:n] { 180 gids[i] = int(v) 181 } 182 return 183 } 184 185 func Setgroups(gids []int) (err error) { 186 if len(gids) == 0 { 187 return setgroups(0, nil) 188 } 189 190 a := make([]_Gid_t, len(gids)) 191 for i, v := range gids { 192 a[i] = _Gid_t(v) 193 } 194 return setgroups(len(a), &a[0]) 195 } 196 197 /* 198 * Socket 199 */ 200 201 //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) 202 203 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 204 var rsa RawSockaddrAny 205 var len _Socklen = SizeofSockaddrAny 206 nfd, err = accept(fd, &rsa, &len) 207 if nfd == -1 { 208 return 209 } 210 sa, err = anyToSockaddr(fd, &rsa) 211 if err != nil { 212 Close(nfd) 213 nfd = 0 214 } 215 return 216 } 217 218 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { 219 // Recvmsg not implemented on AIX 220 return -1, -1, -1, ENOSYS 221 } 222 223 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { 224 // SendmsgN not implemented on AIX 225 return -1, ENOSYS 226 } 227 228 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { 229 switch rsa.Addr.Family { 230 231 case AF_UNIX: 232 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 233 sa := new(SockaddrUnix) 234 235 // Some versions of AIX have a bug in getsockname (see IV78655). 236 // We can't rely on sa.Len being set correctly. 237 n := SizeofSockaddrUnix - 3 // subtract leading Family, Len, terminating NUL. 238 for i := 0; i < n; i++ { 239 if pp.Path[i] == 0 { 240 n = i 241 break 242 } 243 } 244 245 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 246 sa.Name = string(bytes) 247 return sa, nil 248 249 case AF_INET: 250 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 251 sa := new(SockaddrInet4) 252 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 253 sa.Port = int(p[0])<<8 + int(p[1]) 254 sa.Addr = pp.Addr 255 return sa, nil 256 257 case AF_INET6: 258 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 259 sa := new(SockaddrInet6) 260 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 261 sa.Port = int(p[0])<<8 + int(p[1]) 262 sa.ZoneId = pp.Scope_id 263 sa.Addr = pp.Addr 264 return sa, nil 265 } 266 return nil, EAFNOSUPPORT 267 } 268 269 func Gettimeofday(tv *Timeval) (err error) { 270 err = gettimeofday(tv, nil) 271 return 272 } 273 274 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 275 if raceenabled { 276 raceReleaseMerge(unsafe.Pointer(&ioSync)) 277 } 278 return sendfile(outfd, infd, offset, count) 279 } 280 281 // TODO 282 func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 283 return -1, ENOSYS 284 } 285 286 func direntIno(buf []byte) (uint64, bool) { 287 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 288 } 289 290 func direntReclen(buf []byte) (uint64, bool) { 291 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 292 } 293 294 func direntNamlen(buf []byte) (uint64, bool) { 295 reclen, ok := direntReclen(buf) 296 if !ok { 297 return 0, false 298 } 299 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true 300 } 301 302 //sys getdirent(fd int, buf []byte) (n int, err error) 303 func Getdents(fd int, buf []byte) (n int, err error) { 304 return getdirent(fd, buf) 305 } 306 307 //sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error) 308 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 309 var status _C_int 310 var r Pid_t 311 err = ERESTART 312 // AIX wait4 may return with ERESTART errno, while the processus is still 313 // active. 314 for err == ERESTART { 315 r, err = wait4(Pid_t(pid), &status, options, rusage) 316 } 317 wpid = int(r) 318 if wstatus != nil { 319 *wstatus = WaitStatus(status) 320 } 321 return 322 } 323 324 /* 325 * Wait 326 */ 327 328 type WaitStatus uint32 329 330 func (w WaitStatus) Stopped() bool { return w&0x40 != 0 } 331 func (w WaitStatus) StopSignal() Signal { 332 if !w.Stopped() { 333 return -1 334 } 335 return Signal(w>>8) & 0xFF 336 } 337 338 func (w WaitStatus) Exited() bool { return w&0xFF == 0 } 339 func (w WaitStatus) ExitStatus() int { 340 if !w.Exited() { 341 return -1 342 } 343 return int((w >> 8) & 0xFF) 344 } 345 346 func (w WaitStatus) Signaled() bool { return w&0x40 == 0 && w&0xFF != 0 } 347 func (w WaitStatus) Signal() Signal { 348 if !w.Signaled() { 349 return -1 350 } 351 return Signal(w>>16) & 0xFF 352 } 353 354 func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 } 355 356 func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 } 357 358 func (w WaitStatus) TrapCause() int { return -1 } 359 360 //sys ioctl(fd int, req uint, arg uintptr) (err error) 361 362 // fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX 363 // There is no way to create a custom fcntl and to keep //sys fcntl easily, 364 // Therefore, the programmer must call dup2 instead of fcntl in this case. 365 366 // FcntlInt performs a fcntl syscall on fd with the provided command and argument. 367 //sys FcntlInt(fd uintptr, cmd int, arg int) (r int,err error) = fcntl 368 369 // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. 370 //sys FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) = fcntl 371 372 //sys fcntl(fd int, cmd int, arg int) (val int, err error) 373 374 //sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range 375 func Fsync(fd int) error { 376 return fsyncRange(fd, O_SYNC, 0, 0) 377 } 378 379 /* 380 * Direct access 381 */ 382 383 //sys Acct(path string) (err error) 384 //sys Chdir(path string) (err error) 385 //sys Chroot(path string) (err error) 386 //sys Close(fd int) (err error) 387 //sys Dup(oldfd int) (fd int, err error) 388 //sys Exit(code int) 389 //sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) 390 //sys Fchdir(fd int) (err error) 391 //sys Fchmod(fd int, mode uint32) (err error) 392 //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) 393 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 394 //sys Fdatasync(fd int) (err error) 395 // readdir_r 396 //sysnb Getpgid(pid int) (pgid int, err error) 397 398 //sys Getpgrp() (pid int) 399 400 //sysnb Getpid() (pid int) 401 //sysnb Getppid() (ppid int) 402 //sys Getpriority(which int, who int) (prio int, err error) 403 //sysnb Getrusage(who int, rusage *Rusage) (err error) 404 //sysnb Getsid(pid int) (sid int, err error) 405 //sysnb Kill(pid int, sig Signal) (err error) 406 //sys Klogctl(typ int, buf []byte) (n int, err error) = syslog 407 //sys Mkdir(dirfd int, path string, mode uint32) (err error) 408 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) 409 //sys Mkfifo(path string, mode uint32) (err error) 410 //sys Mknod(path string, mode uint32, dev int) (err error) 411 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) 412 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 413 //sys Open(path string, mode int, perm uint32) (fd int, err error) = open64 414 //sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) 415 //sys read(fd int, p []byte) (n int, err error) 416 //sys Readlink(path string, buf []byte) (n int, err error) 417 //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) 418 //sys Setdomainname(p []byte) (err error) 419 //sys Sethostname(p []byte) (err error) 420 //sysnb Setpgid(pid int, pgid int) (err error) 421 //sysnb Setsid() (pid int, err error) 422 //sysnb Settimeofday(tv *Timeval) (err error) 423 424 //sys Setuid(uid int) (err error) 425 //sys Setgid(uid int) (err error) 426 427 //sys Setpriority(which int, who int, prio int) (err error) 428 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) 429 //sys Sync() 430 //sysnb Times(tms *Tms) (ticks uintptr, err error) 431 //sysnb Umask(mask int) (oldmask int) 432 //sysnb Uname(buf *Utsname) (err error) 433 //sys Unlink(path string) (err error) 434 //sys Unlinkat(dirfd int, path string, flags int) (err error) 435 //sys Ustat(dev int, ubuf *Ustat_t) (err error) 436 //sys write(fd int, p []byte) (n int, err error) 437 //sys readlen(fd int, p *byte, np int) (n int, err error) = read 438 //sys writelen(fd int, p *byte, np int) (n int, err error) = write 439 440 //sys Dup2(oldfd int, newfd int) (err error) 441 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = posix_fadvise64 442 //sys Fchown(fd int, uid int, gid int) (err error) 443 //sys fstat(fd int, stat *Stat_t) (err error) 444 //sys fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat 445 //sys Fstatfs(fd int, buf *Statfs_t) (err error) 446 //sys Ftruncate(fd int, length int64) (err error) 447 //sysnb Getegid() (egid int) 448 //sysnb Geteuid() (euid int) 449 //sysnb Getgid() (gid int) 450 //sysnb Getuid() (uid int) 451 //sys Lchown(path string, uid int, gid int) (err error) 452 //sys Listen(s int, n int) (err error) 453 //sys lstat(path string, stat *Stat_t) (err error) 454 //sys Pause() (err error) 455 //sys pread(fd int, p []byte, offset int64) (n int, err error) = pread64 456 //sys pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64 457 //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) 458 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) 459 //sysnb Setregid(rgid int, egid int) (err error) 460 //sysnb Setreuid(ruid int, euid int) (err error) 461 //sys Shutdown(fd int, how int) (err error) 462 //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) 463 //sys stat(path string, statptr *Stat_t) (err error) 464 //sys Statfs(path string, buf *Statfs_t) (err error) 465 //sys Truncate(path string, length int64) (err error) 466 467 //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) 468 //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) 469 //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) 470 //sysnb setgroups(n int, list *_Gid_t) (err error) 471 //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) 472 //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) 473 //sysnb socket(domain int, typ int, proto int) (fd int, err error) 474 //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) 475 //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) 476 //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) 477 //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) 478 //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) 479 480 // In order to use msghdr structure with Control, Controllen, nrecvmsg and nsendmsg must be used. 481 //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = nrecvmsg 482 //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg 483 484 //sys munmap(addr uintptr, length uintptr) (err error) 485 486 var mapper = &mmapper{ 487 active: make(map[*byte][]byte), 488 mmap: mmap, 489 munmap: munmap, 490 } 491 492 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 493 return mapper.Mmap(fd, offset, length, prot, flags) 494 } 495 496 func Munmap(b []byte) (err error) { 497 return mapper.Munmap(b) 498 } 499 500 //sys Madvise(b []byte, advice int) (err error) 501 //sys Mprotect(b []byte, prot int) (err error) 502 //sys Mlock(b []byte) (err error) 503 //sys Mlockall(flags int) (err error) 504 //sys Msync(b []byte, flags int) (err error) 505 //sys Munlock(b []byte) (err error) 506 //sys Munlockall() (err error) 507 508 //sysnb pipe(p *[2]_C_int) (err error) 509 510 func Pipe(p []int) (err error) { 511 if len(p) != 2 { 512 return EINVAL 513 } 514 var pp [2]_C_int 515 err = pipe(&pp) 516 if err == nil { 517 p[0] = int(pp[0]) 518 p[1] = int(pp[1]) 519 } 520 return 521 } 522 523 //sys poll(fds *PollFd, nfds int, timeout int) (n int, err error) 524 525 func Poll(fds []PollFd, timeout int) (n int, err error) { 526 if len(fds) == 0 { 527 return poll(nil, 0, timeout) 528 } 529 return poll(&fds[0], len(fds), timeout) 530 } 531 532 //sys gettimeofday(tv *Timeval, tzp *Timezone) (err error) 533 //sysnb Time(t *Time_t) (tt Time_t, err error) 534 //sys Utime(path string, buf *Utimbuf) (err error) 535 536 //sys Getsystemcfg(label int) (n uint64) 537 538 //sys umount(target string) (err error) 539 func Unmount(target string, flags int) (err error) { 540 if flags != 0 { 541 // AIX doesn't have any flags for umount. 542 return ENOSYS 543 } 544 return umount(target) 545 }