github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/syscall/syscall_solaris.go (about) 1 // Copyright 2009 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 // Solaris system calls. 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 wrap 10 // it in our own nicer implementation, either here or in 11 // syscall_solaris.go or syscall_unix.go. 12 13 package syscall 14 15 import "unsafe" 16 17 // Implemented in asm_solaris_amd64.s. 18 func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 19 func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 20 21 type SockaddrDatalink struct { 22 Family uint16 23 Index uint16 24 Type uint8 25 Nlen uint8 26 Alen uint8 27 Slen uint8 28 Data [244]int8 29 raw RawSockaddrDatalink 30 } 31 32 func direntIno(buf []byte) (uint64, bool) { 33 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 34 } 35 36 func direntReclen(buf []byte) (uint64, bool) { 37 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 38 } 39 40 func direntNamlen(buf []byte) (uint64, bool) { 41 reclen, ok := direntReclen(buf) 42 if !ok { 43 return 0, false 44 } 45 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true 46 } 47 48 func pipe() (r uintptr, w uintptr, err uintptr) 49 50 func Pipe(p []int) (err error) { 51 if len(p) != 2 { 52 return EINVAL 53 } 54 r0, w0, e1 := pipe() 55 if e1 != 0 { 56 err = Errno(e1) 57 } 58 if err == nil { 59 p[0], p[1] = int(r0), int(w0) 60 } 61 return 62 } 63 64 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { 65 if sa.Port < 0 || sa.Port > 0xFFFF { 66 return nil, 0, EINVAL 67 } 68 sa.raw.Family = AF_INET 69 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 70 p[0] = byte(sa.Port >> 8) 71 p[1] = byte(sa.Port) 72 for i := 0; i < len(sa.Addr); i++ { 73 sa.raw.Addr[i] = sa.Addr[i] 74 } 75 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil 76 } 77 78 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { 79 if sa.Port < 0 || sa.Port > 0xFFFF { 80 return nil, 0, EINVAL 81 } 82 sa.raw.Family = AF_INET6 83 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 84 p[0] = byte(sa.Port >> 8) 85 p[1] = byte(sa.Port) 86 sa.raw.Scope_id = sa.ZoneId 87 for i := 0; i < len(sa.Addr); i++ { 88 sa.raw.Addr[i] = sa.Addr[i] 89 } 90 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil 91 } 92 93 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { 94 name := sa.Name 95 n := len(name) 96 if n >= len(sa.raw.Path) { 97 return nil, 0, EINVAL 98 } 99 sa.raw.Family = AF_UNIX 100 for i := 0; i < n; i++ { 101 sa.raw.Path[i] = int8(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(&rsa) 124 } 125 126 const ImplementsGetwd = true 127 128 //sys Getcwd(buf []byte) (n int, err error) 129 130 func Getwd() (wd string, err error) { 131 var buf [PathMax]byte 132 // Getcwd will return an error if it failed for any reason. 133 _, err = Getcwd(buf[0:]) 134 if err != nil { 135 return "", err 136 } 137 n := clen(buf[:]) 138 if n < 1 { 139 return "", EINVAL 140 } 141 return string(buf[:n]), nil 142 } 143 144 /* 145 * Wrapped 146 */ 147 148 //sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error) 149 //sysnb setgroups(ngid int, gid *_Gid_t) (err error) 150 151 func Getgroups() (gids []int, err error) { 152 n, err := getgroups(0, nil) 153 if err != nil { 154 return nil, err 155 } 156 if n == 0 { 157 return nil, nil 158 } 159 160 // Sanity check group count. Max is 16 on BSD. 161 if n < 0 || n > 1000 { 162 return nil, EINVAL 163 } 164 165 a := make([]_Gid_t, n) 166 n, err = getgroups(n, &a[0]) 167 if err != nil { 168 return nil, err 169 } 170 gids = make([]int, n) 171 for i, v := range a[0:n] { 172 gids[i] = int(v) 173 } 174 return 175 } 176 177 func Setgroups(gids []int) (err error) { 178 if len(gids) == 0 { 179 return setgroups(0, nil) 180 } 181 182 a := make([]_Gid_t, len(gids)) 183 for i, v := range gids { 184 a[i] = _Gid_t(v) 185 } 186 return setgroups(len(a), &a[0]) 187 } 188 189 func ReadDirent(fd int, buf []byte) (n int, err error) { 190 // Final argument is (basep *uintptr) and the syscall doesn't take nil. 191 // TODO(rsc): Can we use a single global basep for all calls? 192 return Getdents(fd, buf, new(uintptr)) 193 } 194 195 // Wait status is 7 bits at bottom, either 0 (exited), 196 // 0x7F (stopped), or a signal number that caused an exit. 197 // The 0x80 bit is whether there was a core dump. 198 // An extra number (exit code, signal causing a stop) 199 // is in the high bits. 200 201 type WaitStatus uint32 202 203 const ( 204 mask = 0x7F 205 core = 0x80 206 shift = 8 207 208 exited = 0 209 stopped = 0x7F 210 ) 211 212 func (w WaitStatus) Exited() bool { return w&mask == exited } 213 214 func (w WaitStatus) ExitStatus() int { 215 if w&mask != exited { 216 return -1 217 } 218 return int(w >> shift) 219 } 220 221 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 } 222 223 func (w WaitStatus) Signal() Signal { 224 sig := Signal(w & mask) 225 if sig == stopped || sig == 0 { 226 return -1 227 } 228 return sig 229 } 230 231 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 232 233 func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP } 234 235 func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP } 236 237 func (w WaitStatus) StopSignal() Signal { 238 if !w.Stopped() { 239 return -1 240 } 241 return Signal(w>>shift) & 0xFF 242 } 243 244 func (w WaitStatus) TrapCause() int { return -1 } 245 246 func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr) 247 248 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 249 r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage) 250 if e1 != 0 { 251 err = Errno(e1) 252 } 253 return int(r0), err 254 } 255 256 func gethostname() (name string, err uintptr) 257 258 func Gethostname() (name string, err error) { 259 name, e1 := gethostname() 260 if e1 != 0 { 261 err = Errno(e1) 262 } 263 return name, err 264 } 265 266 func UtimesNano(path string, ts []Timespec) error { 267 if len(ts) != 2 { 268 return EINVAL 269 } 270 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 271 } 272 273 //sys fcntl(fd int, cmd int, arg int) (val int, err error) 274 275 // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. 276 func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { 277 _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0) 278 if e1 != 0 { 279 return e1 280 } 281 return nil 282 } 283 284 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { 285 switch rsa.Addr.Family { 286 case AF_UNIX: 287 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 288 sa := new(SockaddrUnix) 289 // Assume path ends at NUL. 290 // This is not technically the Solaris semantics for 291 // abstract Unix domain sockets -- they are supposed 292 // to be uninterpreted fixed-size binary blobs -- but 293 // everyone uses this convention. 294 n := 0 295 for n < len(pp.Path) && pp.Path[n] != 0 { 296 n++ 297 } 298 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 299 sa.Name = string(bytes) 300 return sa, nil 301 302 case AF_INET: 303 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 304 sa := new(SockaddrInet4) 305 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 306 sa.Port = int(p[0])<<8 + int(p[1]) 307 for i := 0; i < len(sa.Addr); i++ { 308 sa.Addr[i] = pp.Addr[i] 309 } 310 return sa, nil 311 312 case AF_INET6: 313 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 314 sa := new(SockaddrInet6) 315 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 316 sa.Port = int(p[0])<<8 + int(p[1]) 317 sa.ZoneId = pp.Scope_id 318 for i := 0; i < len(sa.Addr); i++ { 319 sa.Addr[i] = pp.Addr[i] 320 } 321 return sa, nil 322 } 323 return nil, EAFNOSUPPORT 324 } 325 326 //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libsocket.accept 327 328 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 329 var rsa RawSockaddrAny 330 var len _Socklen = SizeofSockaddrAny 331 nfd, err = accept(fd, &rsa, &len) 332 if err != nil { 333 return 334 } 335 sa, err = anyToSockaddr(&rsa) 336 if err != nil { 337 Close(nfd) 338 nfd = 0 339 } 340 return 341 } 342 343 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 344 var msg Msghdr 345 var rsa RawSockaddrAny 346 msg.Name = (*byte)(unsafe.Pointer(&rsa)) 347 msg.Namelen = uint32(SizeofSockaddrAny) 348 var iov Iovec 349 if len(p) > 0 { 350 iov.Base = (*int8)(unsafe.Pointer(&p[0])) 351 iov.SetLen(len(p)) 352 } 353 var dummy int8 354 if len(oob) > 0 { 355 // receive at least one normal byte 356 if len(p) == 0 { 357 iov.Base = &dummy 358 iov.SetLen(1) 359 } 360 msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) 361 msg.Accrightslen = int32(len(oob)) 362 } 363 msg.Iov = &iov 364 msg.Iovlen = 1 365 if n, err = recvmsg(fd, &msg, flags); err != nil { 366 return 367 } 368 oobn = int(msg.Accrightslen) 369 // source address is only specified if the socket is unconnected 370 if rsa.Addr.Family != AF_UNSPEC { 371 from, err = anyToSockaddr(&rsa) 372 } 373 return 374 } 375 376 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 377 _, err = SendmsgN(fd, p, oob, to, flags) 378 return 379 } 380 381 //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg 382 383 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 384 var ptr unsafe.Pointer 385 var salen _Socklen 386 if to != nil { 387 ptr, salen, err = to.sockaddr() 388 if err != nil { 389 return 0, err 390 } 391 } 392 var msg Msghdr 393 msg.Name = (*byte)(unsafe.Pointer(ptr)) 394 msg.Namelen = uint32(salen) 395 var iov Iovec 396 if len(p) > 0 { 397 iov.Base = (*int8)(unsafe.Pointer(&p[0])) 398 iov.SetLen(len(p)) 399 } 400 var dummy int8 401 if len(oob) > 0 { 402 // send at least one normal byte 403 if len(p) == 0 { 404 iov.Base = &dummy 405 iov.SetLen(1) 406 } 407 msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) 408 msg.Accrightslen = int32(len(oob)) 409 } 410 msg.Iov = &iov 411 msg.Iovlen = 1 412 if n, err = sendmsg(fd, &msg, flags); err != nil { 413 return 0, err 414 } 415 if len(oob) > 0 && len(p) == 0 { 416 n = 0 417 } 418 return n, nil 419 } 420 421 /* 422 * Exposed directly 423 */ 424 //sys Access(path string, mode uint32) (err error) 425 //sys Adjtime(delta *Timeval, olddelta *Timeval) (err error) 426 //sys Chdir(path string) (err error) 427 //sys Chmod(path string, mode uint32) (err error) 428 //sys Chown(path string, uid int, gid int) (err error) 429 //sys Chroot(path string) (err error) 430 //sys Close(fd int) (err error) 431 //sys Dup(fd int) (nfd int, err error) 432 //sys Fchdir(fd int) (err error) 433 //sys Fchmod(fd int, mode uint32) (err error) 434 //sys Fchown(fd int, uid int, gid int) (err error) 435 //sys Fpathconf(fd int, name int) (val int, err error) 436 //sys Fstat(fd int, stat *Stat_t) (err error) 437 //sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) 438 //sysnb Getgid() (gid int) 439 //sysnb Getpid() (pid int) 440 //sys Geteuid() (euid int) 441 //sys Getegid() (egid int) 442 //sys Getppid() (ppid int) 443 //sys Getpriority(which int, who int) (n int, err error) 444 //sysnb Getrlimit(which int, lim *Rlimit) (err error) 445 //sysnb Gettimeofday(tv *Timeval) (err error) 446 //sysnb Getuid() (uid int) 447 //sys Kill(pid int, signum Signal) (err error) 448 //sys Lchown(path string, uid int, gid int) (err error) 449 //sys Link(path string, link string) (err error) 450 //sys Listen(s int, backlog int) (err error) = libsocket.__xnet_listen 451 //sys Lstat(path string, stat *Stat_t) (err error) 452 //sys Mkdir(path string, mode uint32) (err error) 453 //sys Mknod(path string, mode uint32, dev int) (err error) 454 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 455 //sys Open(path string, mode int, perm uint32) (fd int, err error) 456 //sys Pathconf(path string, name int) (val int, err error) 457 //sys Pread(fd int, p []byte, offset int64) (n int, err error) 458 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) 459 //sys read(fd int, p []byte) (n int, err error) 460 //sys Readlink(path string, buf []byte) (n int, err error) 461 //sys Rename(from string, to string) (err error) 462 //sys Rmdir(path string) (err error) 463 //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek 464 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile 465 //sysnb Setegid(egid int) (err error) 466 //sysnb Seteuid(euid int) (err error) 467 //sysnb Setgid(gid int) (err error) 468 //sysnb Setpgid(pid int, pgid int) (err error) 469 //sys Setpriority(which int, who int, prio int) (err error) 470 //sysnb Setregid(rgid int, egid int) (err error) 471 //sysnb Setreuid(ruid int, euid int) (err error) 472 //sysnb Setrlimit(which int, lim *Rlimit) (err error) 473 //sysnb Setsid() (pid int, err error) 474 //sysnb Setuid(uid int) (err error) 475 //sys Shutdown(s int, how int) (err error) = libsocket.shutdown 476 //sys Stat(path string, stat *Stat_t) (err error) 477 //sys Symlink(path string, link string) (err error) 478 //sys Sync() (err error) 479 //sys Truncate(path string, length int64) (err error) 480 //sys Fsync(fd int) (err error) 481 //sys Ftruncate(fd int, length int64) (err error) 482 //sys Umask(newmask int) (oldmask int) 483 //sys Unlink(path string) (err error) 484 //sys utimes(path string, times *[2]Timeval) (err error) 485 //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_bind 486 //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect 487 //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) 488 //sys munmap(addr uintptr, length uintptr) (err error) 489 //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto 490 //sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket 491 //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair 492 //sys write(fd int, p []byte) (n int, err error) 493 //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.__xnet_getsockopt 494 //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername 495 //sys getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname 496 //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt 497 //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom 498 //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg 499 //sys getexecname() (path unsafe.Pointer, err error) = libc.getexecname 500 //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) 501 502 func Getexecname() (path string, err error) { 503 ptr, err := getexecname() 504 if err != nil { 505 return "", err 506 } 507 bytes := (*[1 << 29]byte)(ptr)[:] 508 for i, b := range bytes { 509 if b == 0 { 510 return string(bytes[:i]), nil 511 } 512 } 513 panic("unreachable") 514 } 515 516 func readlen(fd int, buf *byte, nbuf int) (n int, err error) { 517 r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) 518 n = int(r0) 519 if e1 != 0 { 520 err = e1 521 } 522 return 523 } 524 525 func writelen(fd int, buf *byte, nbuf int) (n int, err error) { 526 r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_write)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) 527 n = int(r0) 528 if e1 != 0 { 529 err = e1 530 } 531 return 532 } 533 534 func Utimes(path string, tv []Timeval) error { 535 if len(tv) != 2 { 536 return EINVAL 537 } 538 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 539 }