github.com/golang-haiku/go-1.4.3@v0.0.0-20190609233734-1f5ae41cc308/src/syscall/syscall_haiku.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 "runtime" 16 import "unsafe" 17 18 /*type SockaddrDatalink struct { 19 Family uint16 20 Index uint16 21 Type uint8 22 Nlen uint8 23 Alen uint8 24 Slen uint8 25 Data [244]int8 26 raw RawSockaddrDatalink 27 }*/ 28 29 func clen(n []byte) int { 30 for i := 0; i < len(n); i++ { 31 if n[i] == 0 { 32 return i 33 } 34 } 35 return len(n) 36 } 37 38 // ParseDirent parses up to max directory entries in buf, 39 // appending the names to names. It returns the number 40 // bytes consumed from buf, the number of entries added 41 // to names, and the new names slice. 42 func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { 43 origlen := len(buf) 44 for max != 0 && len(buf) > 0 { 45 dirent := (*Dirent)(unsafe.Pointer(&buf[0])) 46 if dirent.Reclen == 0 { 47 buf = nil 48 break 49 } 50 buf = buf[dirent.Reclen:] 51 if dirent.Ino == 0 { // File absent in directory. 52 continue 53 } 54 bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) 55 var name = string(bytes[0:clen(bytes[:])]) 56 if name == "." || name == ".." { // Useless names 57 continue 58 } 59 max-- 60 count++ 61 names = append(names, name) 62 } 63 return origlen - len(buf), count, names 64 } 65 66 func pipe() (r uintptr, w uintptr, err uintptr) 67 68 //sys pipe2(fds []int) (err error) = libroot.pipe 69 70 func Pipe(p []int) (err error) { 71 if len(p) != 2 { 72 return EINVAL 73 } 74 if runtime.GOARCH == "386" { 75 return pipe2(p) 76 } 77 r0, w0, e1 := pipe() 78 if e1 != 0 { 79 err = Errno(e1) 80 } 81 p[0], p[1] = int(r0), int(w0) 82 return 83 } 84 85 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { 86 if sa.Port < 0 || sa.Port > 0xFFFF { 87 return nil, 0, EINVAL 88 } 89 sa.raw.Family = AF_INET 90 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 91 p[0] = byte(sa.Port >> 8) 92 p[1] = byte(sa.Port) 93 for i := 0; i < len(sa.Addr); i++ { 94 sa.raw.Addr[i] = sa.Addr[i] 95 } 96 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil 97 } 98 99 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { 100 if sa.Port < 0 || sa.Port > 0xFFFF { 101 return nil, 0, EINVAL 102 } 103 sa.raw.Family = AF_INET6 104 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 105 p[0] = byte(sa.Port >> 8) 106 p[1] = byte(sa.Port) 107 sa.raw.Scope_id = sa.ZoneId 108 for i := 0; i < len(sa.Addr); i++ { 109 sa.raw.Addr[i] = sa.Addr[i] 110 } 111 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil 112 } 113 114 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { 115 name := sa.Name 116 n := len(name) 117 if n >= len(sa.raw.Path) { 118 return nil, 0, EINVAL 119 } 120 sa.raw.Family = AF_UNIX 121 for i := 0; i < n; i++ { 122 sa.raw.Path[i] = int8(name[i]) 123 } 124 // length is family (uint16), name, NUL. 125 sl := _Socklen(2) 126 if n > 0 { 127 sl += _Socklen(n) + 1 128 } 129 if sa.raw.Path[0] == '@' { 130 sa.raw.Path[0] = 0 131 // Don't count trailing NUL for abstract address. 132 sl-- 133 } 134 135 return unsafe.Pointer(&sa.raw), sl, nil 136 } 137 138 func Getsockname(fd int) (sa Sockaddr, err error) { 139 var rsa RawSockaddrAny 140 var len _Socklen = SizeofSockaddrAny 141 if err = getsockname(fd, &rsa, &len); err != nil { 142 return 143 } 144 return anyToSockaddr(&rsa) 145 } 146 147 // The const provides a compile-time constant so clients 148 // can adjust to whether there is a working Getwd and avoid 149 // even linking this function into the binary. See ../os/getwd.go. 150 const ImplementsGetwd = false 151 152 func Getwd() (string, error) { return "", ENOTSUP } 153 154 /* 155 * Wrapped 156 */ 157 158 //sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error) 159 //sysnb setgroups(ngid int, gid *_Gid_t) (err error) 160 161 func Getgroups() (gids []int, err error) { 162 n, err := getgroups(0, nil) 163 if err != nil { 164 return nil, err 165 } 166 if n == 0 { 167 return nil, nil 168 } 169 170 // Sanity check group count. Max is 16 on BSD. 171 if n < 0 || n > 1000 { 172 return nil, EINVAL 173 } 174 175 a := make([]_Gid_t, n) 176 n, err = getgroups(n, &a[0]) 177 if err != nil { 178 return nil, err 179 } 180 gids = make([]int, n) 181 for i, v := range a[0:n] { 182 gids[i] = int(v) 183 } 184 return 185 } 186 187 func Setgroups(gids []int) (err error) { 188 if len(gids) == 0 { 189 return setgroups(0, nil) 190 } 191 192 a := make([]_Gid_t, len(gids)) 193 for i, v := range gids { 194 a[i] = _Gid_t(v) 195 } 196 return setgroups(len(a), &a[0]) 197 } 198 199 func ReadDirent(fd int, buf []byte) (n int, err error) { 200 panic("Not implemented") 201 } 202 203 // Wait status: 8 bits at the bottom is exit status 204 // If all bits other than the 8 bottom are empty, then exited 205 // next 8 bits are signal number that caused exit 206 // next 8 bits are signal that caused stop 207 // core is 0x10000 208 // continued is 0x20000 209 210 type WaitStatus uint32 211 212 const ( 213 mask = 0xFF 214 core = 0x10000 215 continued = 0x20000 216 shift = 8 217 218 exited = 0 219 ) 220 221 func (w WaitStatus) Exited() bool { return w&^mask == exited } 222 223 func (w WaitStatus) ExitStatus() int { 224 if w&^mask != exited { 225 return -1 226 } 227 return int(w & mask) 228 } 229 230 func (w WaitStatus) Signaled() bool { return ((w >> 8) & mask) != 0 } 231 232 func (w WaitStatus) Signal() Signal { 233 sig := Signal((w >> 8) & mask) 234 if sig == 0 { 235 return -1 236 } 237 return sig 238 } 239 240 func (w WaitStatus) CoreDump() bool { return w&core != 0 } 241 242 func (w WaitStatus) Stopped() bool { return (w>>16)&mask != 0 } 243 244 func (w WaitStatus) Continued() bool { return w&continued != 0 } 245 246 func (w WaitStatus) StopSignal() Signal { 247 if !w.Stopped() { 248 return -1 249 } 250 return Signal(w>>16) & mask 251 } 252 253 func (w WaitStatus) TrapCause() int { return -1 } 254 255 //sys Wait4(pid int, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid int, err error) = libroot.waitpid 256 257 func gethostname() (name string, err uintptr) 258 259 func Gethostname() (name string, err error) { 260 name, e1 := gethostname() 261 if e1 != 0 { 262 err = Errno(e1) 263 } 264 return name, err 265 } 266 267 func UtimesNano(path string, ts []Timespec) (err error) { 268 if len(ts) != 2 { 269 return EINVAL 270 } 271 var tv [2]Timeval 272 for i := 0; i < 2; i++ { 273 tv[i].Sec = ts[i].Sec 274 tv[i].Usec = int32(ts[i].Nsec / 1000) 275 } 276 return Utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 277 } 278 279 //sys fcntl(fd int, cmd int, arg int) (val int, err error) 280 281 // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. 282 func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { 283 _, _, e1 := sysvicall6(procfcntl.Addr(), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0) 284 if e1 != 0 { 285 return e1 286 } 287 return nil 288 } 289 290 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { 291 switch rsa.Addr.Family { 292 case AF_UNIX: 293 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 294 sa := new(SockaddrUnix) 295 // Assume path ends at NUL. 296 // This is not technically the Solaris semantics for 297 // abstract Unix domain sockets -- they are supposed 298 // to be uninterpreted fixed-size binary blobs -- but 299 // everyone uses this convention. 300 n := 0 301 for n < len(pp.Path) && pp.Path[n] != 0 { 302 n++ 303 } 304 bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 305 sa.Name = string(bytes) 306 return sa, nil 307 308 case AF_INET: 309 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 310 sa := new(SockaddrInet4) 311 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 312 sa.Port = int(p[0])<<8 + int(p[1]) 313 for i := 0; i < len(sa.Addr); i++ { 314 sa.Addr[i] = pp.Addr[i] 315 } 316 return sa, nil 317 318 case AF_INET6: 319 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 320 sa := new(SockaddrInet6) 321 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 322 sa.Port = int(p[0])<<8 + int(p[1]) 323 sa.ZoneId = pp.Scope_id 324 for i := 0; i < len(sa.Addr); i++ { 325 sa.Addr[i] = pp.Addr[i] 326 } 327 return sa, nil 328 } 329 return nil, EAFNOSUPPORT 330 } 331 332 //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libnetwork.accept 333 334 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 335 var rsa RawSockaddrAny 336 var len _Socklen = SizeofSockaddrAny 337 nfd, err = accept(fd, &rsa, &len) 338 if err != nil { 339 return 340 } 341 sa, err = anyToSockaddr(&rsa) 342 if err != nil { 343 Close(nfd) 344 nfd = 0 345 } 346 return 347 } 348 349 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 350 var msg Msghdr 351 var rsa RawSockaddrAny 352 msg.Name = (*byte)(unsafe.Pointer(&rsa)) 353 msg.Namelen = uint32(SizeofSockaddrAny) 354 var iov Iovec 355 if len(p) > 0 { 356 iov.Base = (*byte)(unsafe.Pointer(&p[0])) 357 iov.SetLen(len(p)) 358 } 359 var dummy byte 360 if len(oob) > 0 { 361 // receive at least one normal byte 362 if len(p) == 0 { 363 iov.Base = &dummy 364 iov.SetLen(1) 365 } 366 //msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) 367 } 368 msg.Iov = &iov 369 msg.Iovlen = 1 370 if n, err = recvmsg(fd, &msg, flags); err != nil { 371 return 372 } 373 oobn = 0 //int(msg.Accrightslen) 374 // source address is only specified if the socket is unconnected 375 if rsa.Addr.Family != AF_UNSPEC { 376 from, err = anyToSockaddr(&rsa) 377 } 378 return 379 } 380 381 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 382 _, err = SendmsgN(fd, p, oob, to, flags) 383 return 384 } 385 386 //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libnetwork.sendmsg 387 388 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 389 var ptr unsafe.Pointer 390 var salen _Socklen 391 if to != nil { 392 ptr, salen, err = to.sockaddr() 393 if err != nil { 394 return 0, err 395 } 396 } 397 var msg Msghdr 398 msg.Name = (*byte)(unsafe.Pointer(ptr)) 399 msg.Namelen = uint32(salen) 400 var iov Iovec 401 if len(p) > 0 { 402 iov.Base = (*byte)(unsafe.Pointer(&p[0])) 403 iov.SetLen(len(p)) 404 } 405 var dummy byte 406 if len(oob) > 0 { 407 // send at least one normal byte 408 if len(p) == 0 { 409 iov.Base = &dummy 410 iov.SetLen(1) 411 } 412 //msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) 413 } 414 msg.Iov = &iov 415 msg.Iovlen = 1 416 if n, err = sendmsg(fd, &msg, flags); err != nil { 417 return 0, err 418 } 419 if len(oob) > 0 && len(p) == 0 { 420 n = 0 421 } 422 return n, nil 423 } 424 425 // FIXME: haiku: fix the auto generator so that it can deal with more than 6 params 426 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) 427 428 /* 429 * Exposed directly 430 */ 431 //sys Access(path string, mode uint32) (err error) 432 //sys Adjtime(delta *Timeval, olddelta *Timeval) (err error) 433 //sys Chdir(path string) (err error) 434 //sys Chmod(path string, mode uint32) (err error) 435 //sys Chown(path string, uid int, gid int) (err error) 436 //sys Chroot(path string) (err error) 437 //sys Close(fd int) (err error) 438 //sys Dup(fd int) (nfd int, err error) 439 //sys Exit(code int) 440 //sys Fchdir(fd int) (err error) 441 //sys Fchmod(fd int, mode uint32) (err error) 442 //sys Fchown(fd int, uid int, gid int) (err error) 443 //sys Fpathconf(fd int, name int) (val int, err error) 444 //sys Fstat(fd int, stat *Stat_t) (err error) 445 //sysnb Getgid() (gid int) 446 //sysnb Getpid() (pid int) 447 //sys Geteuid() (euid int) 448 //sys Getegid() (egid int) 449 //sys Getppid() (ppid int) 450 //sys Getpriority(which int, who int) (n int, err error) 451 //sysnb Getrlimit(which int, lim *Rlimit) (err error) 452 //sysnb Gettimeofday(tv *Timeval) (err error) 453 //sysnb Getuid() (uid int) 454 //sys Kill(pid int, signum Signal) (err error) 455 //sys Lchown(path string, uid int, gid int) (err error) 456 //sys Link(path string, link string) (err error) 457 //sys Listen(s int, backlog int) (err error) = libnetwork.listen 458 //sys Lstat(path string, stat *Stat_t) (err error) 459 //sys Mkdir(path string, mode uint32) (err error) 460 //sys Mknod(path string, mode uint32, dev int) (err error) 461 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 462 //sys Open(path string, mode int, perm uint32) (fd int, err error) 463 //sys Pathconf(path string, name int) (val int, err error) 464 //sys Pread(fd int, p []byte, offset int64) (n int, err error) 465 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) 466 //sys read(fd int, p []byte) (n int, err error) 467 //sys Readlink(path string, buf []byte) (n int, err error) 468 //sys Rename(from string, to string) (err error) 469 //sys Rmdir(path string) (err error) 470 //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek 471 //sysnb Setegid(egid int) (err error) 472 //sysnb Seteuid(euid int) (err error) 473 //sysnb Setgid(gid int) (err error) 474 //sysnb Setpgid(pid int, pgid int) (err error) 475 //sys Setpriority(which int, who int, prio int) (err error) 476 //sysnb Setregid(rgid int, egid int) (err error) 477 //sysnb Setreuid(ruid int, euid int) (err error) 478 //sysnb Setrlimit(which int, lim *Rlimit) (err error) 479 //sysnb Setsid() (pid int, err error) 480 //sysnb Setuid(uid int) (err error) 481 //sys Shutdown(s int, how int) (err error) = libnetwork.shutdown 482 //sys Stat(path string, stat *Stat_t) (err error) 483 //sys Symlink(path string, link string) (err error) 484 //sys Sync() (err error) 485 //sys Truncate(path string, length int64) (err error) 486 //sys Fsync(fd int) (err error) 487 //sys Ftruncate(fd int, length int64) (err error) 488 //sys Umask(newmask int) (oldmask int) 489 //sys Unlink(path string) (err error) 490 //sys Utimes(path string, times *[2]Timeval) (err error) 491 //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libnetwork.bind 492 //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libnetwork.connect 493 /*//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)*/ 494 //sys munmap(addr uintptr, length uintptr) (err error) 495 //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libnetwork.sendto 496 //sys socket(domain int, typ int, proto int) (fd int, err error) = libnetwork.socket 497 //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libnetwork.socketpair 498 //sys write(fd int, p []byte) (n int, err error) 499 //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libnetwork.getsockopt 500 //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libnetwork.getpeername 501 //sys getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libnetwork.getsockname 502 //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libnetwork.setsockopt 503 //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libnetwork.recvfrom 504 //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libnetwork.recvmsg 505 506 //sys Fdopendir(fd int) (dir unsafe.Pointer, err error) 507 //sys Readdir_r(dir unsafe.Pointer, entry *Dirent, result **Dirent) (status int) 508 //sys Closedir(dir unsafe.Pointer) (status int, err error) 509 510 func readlen(fd int, buf *byte, nbuf int) (n int, err error) { 511 r0, _, e1 := sysvicall6(procread.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) 512 n = int(r0) 513 if e1 != 0 { 514 err = e1 515 } 516 return 517 } 518 519 func writelen(fd int, buf *byte, nbuf int) (n int, err error) { 520 r0, _, e1 := sysvicall6(procwrite.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) 521 n = int(r0) 522 if e1 != 0 { 523 err = e1 524 } 525 return 526 } 527 528 var mapper = &mmapper{ 529 active: make(map[*byte][]byte), 530 mmap: mmap, 531 munmap: munmap, 532 } 533 534 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 535 return mapper.Mmap(fd, offset, length, prot, flags) 536 } 537 538 func Munmap(b []byte) (err error) { 539 return mapper.Munmap(b) 540 }