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