Source file src/pkg/syscall/syscall_linux.go
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 // Linux 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 10 // wrap it in our own nicer implementation. 11 12 package syscall 13 14 import "unsafe" 15 16 /* 17 * Wrapped 18 */ 19 20 //sys open(path string, mode int, perm uint32) (fd int, err error) 21 func Open(path string, mode int, perm uint32) (fd int, err error) { 22 return open(path, mode|O_LARGEFILE, perm) 23 } 24 25 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) 26 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { 27 return openat(dirfd, path, flags|O_LARGEFILE, mode) 28 } 29 30 //sysnb pipe(p *[2]_C_int) (err error) 31 func Pipe(p []int) (err error) { 32 if len(p) != 2 { 33 return EINVAL 34 } 35 var pp [2]_C_int 36 err = pipe(&pp) 37 p[0] = int(pp[0]) 38 p[1] = int(pp[1]) 39 return 40 } 41 42 //sys utimes(path string, times *[2]Timeval) (err error) 43 func Utimes(path string, tv []Timeval) (err error) { 44 if len(tv) != 2 { 45 return EINVAL 46 } 47 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 48 } 49 50 //sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) 51 func Futimesat(dirfd int, path string, tv []Timeval) (err error) { 52 if len(tv) != 2 { 53 return EINVAL 54 } 55 return futimesat(dirfd, StringBytePtr(path), (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 56 } 57 58 func Futimes(fd int, tv []Timeval) (err error) { 59 // Believe it or not, this is the best we can do on Linux 60 // (and is what glibc does). 61 return Utimes("/proc/self/fd/"+itoa(fd), tv) 62 } 63 64 const ImplementsGetwd = true 65 66 //sys Getcwd(buf []byte) (n int, err error) 67 func Getwd() (wd string, err error) { 68 var buf [PathMax]byte 69 n, err := Getcwd(buf[0:]) 70 if err != nil { 71 return "", err 72 } 73 // Getcwd returns the number of bytes written to buf, including the NUL. 74 if n < 1 || n > len(buf) || buf[n-1] != 0 { 75 return "", EINVAL 76 } 77 return string(buf[0 : n-1]), nil 78 } 79 80 func Getgroups() (gids []int, err error) { 81 n, err := getgroups(0, nil) 82 if err != nil { 83 return nil, err 84 } 85 if n == 0 { 86 return nil, nil 87 } 88 89 // Sanity check group count. Max is 1<<16 on Linux. 90 if n < 0 || n > 1<<20 { 91 return nil, EINVAL 92 } 93 94 a := make([]_Gid_t, n) 95 n, err = getgroups(n, &a[0]) 96 if err != nil { 97 return nil, err 98 } 99 gids = make([]int, n) 100 for i, v := range a[0:n] { 101 gids[i] = int(v) 102 } 103 return 104 } 105 106 func Setgroups(gids []int) (err error) { 107 if len(gids) == 0 { 108 return setgroups(0, nil) 109 } 110 111 a := make([]_Gid_t, len(gids)) 112 for i, v := range gids { 113 a[i] = _Gid_t(v) 114 } 115 return setgroups(len(a), &a[0]) 116 } 117 118 type WaitStatus uint32 119 120 // Wait status is 7 bits at bottom, either 0 (exited), 121 // 0x7F (stopped), or a signal number that caused an exit. 122 // The 0x80 bit is whether there was a core dump. 123 // An extra number (exit code, signal causing a stop) 124 // is in the high bits. At least that's the idea. 125 // There are various irregularities. For example, the 126 // "continued" status is 0xFFFF, distinguishing itself 127 // from stopped via the core dump bit. 128 129 const ( 130 mask = 0x7F 131 core = 0x80 132 exited = 0x00 133 stopped = 0x7F 134 shift = 8 135 ) 136 137 func (w WaitStatus) Exited() bool { return w&mask == exited } 138 139 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited } 140 141 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped } 142 143 func (w WaitStatus) Continued() bool { return w == 0xFFFF } 144 145 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 146 147 func (w WaitStatus) ExitStatus() int { 148 if !w.Exited() { 149 return -1 150 } 151 return int(w>>shift) & 0xFF 152 } 153 154 func (w WaitStatus) Signal() Signal { 155 if !w.Signaled() { 156 return -1 157 } 158 return Signal(w & mask) 159 } 160 161 func (w WaitStatus) StopSignal() Signal { 162 if !w.Stopped() { 163 return -1 164 } 165 return Signal(w>>shift) & 0xFF 166 } 167 168 func (w WaitStatus) TrapCause() int { 169 if w.StopSignal() != SIGTRAP { 170 return -1 171 } 172 return int(w>>shift) >> 8 173 } 174 175 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) 176 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 177 var status _C_int 178 wpid, err = wait4(pid, &status, options, rusage) 179 if wstatus != nil { 180 *wstatus = WaitStatus(status) 181 } 182 return 183 } 184 185 func Mkfifo(path string, mode uint32) (err error) { 186 return Mknod(path, mode|S_IFIFO, 0) 187 } 188 189 // For testing: clients can set this flag to force 190 // creation of IPv6 sockets to return EAFNOSUPPORT. 191 var SocketDisableIPv6 bool 192 193 type Sockaddr interface { 194 sockaddr() (ptr uintptr, len _Socklen, err error) // lowercase; only we can define Sockaddrs 195 } 196 197 type SockaddrInet4 struct { 198 Port int 199 Addr [4]byte 200 raw RawSockaddrInet4 201 } 202 203 func (sa *SockaddrInet4) sockaddr() (uintptr, _Socklen, error) { 204 if sa.Port < 0 || sa.Port > 0xFFFF { 205 return 0, 0, EINVAL 206 } 207 sa.raw.Family = AF_INET 208 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 209 p[0] = byte(sa.Port >> 8) 210 p[1] = byte(sa.Port) 211 for i := 0; i < len(sa.Addr); i++ { 212 sa.raw.Addr[i] = sa.Addr[i] 213 } 214 return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet4, nil 215 } 216 217 type SockaddrInet6 struct { 218 Port int 219 ZoneId uint32 220 Addr [16]byte 221 raw RawSockaddrInet6 222 } 223 224 func (sa *SockaddrInet6) sockaddr() (uintptr, _Socklen, error) { 225 if sa.Port < 0 || sa.Port > 0xFFFF { 226 return 0, 0, EINVAL 227 } 228 sa.raw.Family = AF_INET6 229 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 230 p[0] = byte(sa.Port >> 8) 231 p[1] = byte(sa.Port) 232 sa.raw.Scope_id = sa.ZoneId 233 for i := 0; i < len(sa.Addr); i++ { 234 sa.raw.Addr[i] = sa.Addr[i] 235 } 236 return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6, nil 237 } 238 239 type SockaddrUnix struct { 240 Name string 241 raw RawSockaddrUnix 242 } 243 244 func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, error) { 245 name := sa.Name 246 n := len(name) 247 if n >= len(sa.raw.Path) || n == 0 { 248 return 0, 0, EINVAL 249 } 250 sa.raw.Family = AF_UNIX 251 for i := 0; i < n; i++ { 252 sa.raw.Path[i] = int8(name[i]) 253 } 254 // length is family (uint16), name, NUL. 255 sl := 2 + _Socklen(n) + 1 256 if sa.raw.Path[0] == '@' { 257 sa.raw.Path[0] = 0 258 // Don't count trailing NUL for abstract address. 259 sl-- 260 } 261 262 return uintptr(unsafe.Pointer(&sa.raw)), sl, nil 263 } 264 265 type SockaddrLinklayer struct { 266 Protocol uint16 267 Ifindex int 268 Hatype uint16 269 Pkttype uint8 270 Halen uint8 271 Addr [8]byte 272 raw RawSockaddrLinklayer 273 } 274 275 func (sa *SockaddrLinklayer) sockaddr() (uintptr, _Socklen, error) { 276 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 277 return 0, 0, EINVAL 278 } 279 sa.raw.Family = AF_PACKET 280 sa.raw.Protocol = sa.Protocol 281 sa.raw.Ifindex = int32(sa.Ifindex) 282 sa.raw.Hatype = sa.Hatype 283 sa.raw.Pkttype = sa.Pkttype 284 sa.raw.Halen = sa.Halen 285 for i := 0; i < len(sa.Addr); i++ { 286 sa.raw.Addr[i] = sa.Addr[i] 287 } 288 return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrLinklayer, nil 289 } 290 291 type SockaddrNetlink struct { 292 Family uint16 293 Pad uint16 294 Pid uint32 295 Groups uint32 296 raw RawSockaddrNetlink 297 } 298 299 func (sa *SockaddrNetlink) sockaddr() (uintptr, _Socklen, error) { 300 sa.raw.Family = AF_NETLINK 301 sa.raw.Pad = sa.Pad 302 sa.raw.Pid = sa.Pid 303 sa.raw.Groups = sa.Groups 304 return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrNetlink, nil 305 } 306 307 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { 308 switch rsa.Addr.Family { 309 case AF_NETLINK: 310 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) 311 sa := new(SockaddrNetlink) 312 sa.Family = pp.Family 313 sa.Pad = pp.Pad 314 sa.Pid = pp.Pid 315 sa.Groups = pp.Groups 316 return sa, nil 317 318 case AF_PACKET: 319 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa)) 320 sa := new(SockaddrLinklayer) 321 sa.Protocol = pp.Protocol 322 sa.Ifindex = int(pp.Ifindex) 323 sa.Hatype = pp.Hatype 324 sa.Pkttype = pp.Pkttype 325 sa.Halen = pp.Halen 326 for i := 0; i < len(sa.Addr); i++ { 327 sa.Addr[i] = pp.Addr[i] 328 } 329 return sa, nil 330 331 case AF_UNIX: 332 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 333 sa := new(SockaddrUnix) 334 if pp.Path[0] == 0 { 335 // "Abstract" Unix domain socket. 336 // Rewrite leading NUL as @ for textual display. 337 // (This is the standard convention.) 338 // Not friendly to overwrite in place, 339 // but the callers below don't care. 340 pp.Path[0] = '@' 341 } 342 343 // Assume path ends at NUL. 344 // This is not technically the Linux semantics for 345 // abstract Unix domain sockets--they are supposed 346 // to be uninterpreted fixed-size binary blobs--but 347 // everyone uses this convention. 348 n := 0 349 for n < len(pp.Path) && pp.Path[n] != 0 { 350 n++ 351 } 352 bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 353 sa.Name = string(bytes) 354 return sa, nil 355 356 case AF_INET: 357 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 358 sa := new(SockaddrInet4) 359 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 360 sa.Port = int(p[0])<<8 + int(p[1]) 361 for i := 0; i < len(sa.Addr); i++ { 362 sa.Addr[i] = pp.Addr[i] 363 } 364 return sa, nil 365 366 case AF_INET6: 367 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 368 sa := new(SockaddrInet6) 369 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 370 sa.Port = int(p[0])<<8 + int(p[1]) 371 sa.ZoneId = pp.Scope_id 372 for i := 0; i < len(sa.Addr); i++ { 373 sa.Addr[i] = pp.Addr[i] 374 } 375 return sa, nil 376 } 377 return nil, EAFNOSUPPORT 378 } 379 380 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 381 var rsa RawSockaddrAny 382 var len _Socklen = SizeofSockaddrAny 383 nfd, err = accept(fd, &rsa, &len) 384 if err != nil { 385 return 386 } 387 sa, err = anyToSockaddr(&rsa) 388 if err != nil { 389 Close(nfd) 390 nfd = 0 391 } 392 return 393 } 394 395 func Getsockname(fd int) (sa Sockaddr, err error) { 396 var rsa RawSockaddrAny 397 var len _Socklen = SizeofSockaddrAny 398 if err = getsockname(fd, &rsa, &len); err != nil { 399 return 400 } 401 return anyToSockaddr(&rsa) 402 } 403 404 func Getpeername(fd int) (sa Sockaddr, err error) { 405 var rsa RawSockaddrAny 406 var len _Socklen = SizeofSockaddrAny 407 if err = getpeername(fd, &rsa, &len); err != nil { 408 return 409 } 410 return anyToSockaddr(&rsa) 411 } 412 413 func Bind(fd int, sa Sockaddr) (err error) { 414 ptr, n, err := sa.sockaddr() 415 if err != nil { 416 return err 417 } 418 return bind(fd, ptr, n) 419 } 420 421 func Connect(fd int, sa Sockaddr) (err error) { 422 ptr, n, err := sa.sockaddr() 423 if err != nil { 424 return err 425 } 426 return connect(fd, ptr, n) 427 } 428 429 func Socket(domain, typ, proto int) (fd int, err error) { 430 if domain == AF_INET6 && SocketDisableIPv6 { 431 return -1, EAFNOSUPPORT 432 } 433 fd, err = socket(domain, typ, proto) 434 return 435 } 436 437 func Socketpair(domain, typ, proto int) (fd [2]int, err error) { 438 err = socketpair(domain, typ, proto, &fd) 439 return 440 } 441 442 func GetsockoptInt(fd, level, opt int) (value int, err error) { 443 var n int32 444 vallen := _Socklen(4) 445 err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), &vallen) 446 return int(n), err 447 } 448 449 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) { 450 vallen := _Socklen(4) 451 err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), &vallen) 452 return value, err 453 } 454 455 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) { 456 var value IPMreq 457 vallen := _Socklen(SizeofIPMreq) 458 err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen) 459 return &value, err 460 } 461 462 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { 463 var value IPMreqn 464 vallen := _Socklen(SizeofIPMreqn) 465 err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen) 466 return &value, err 467 } 468 469 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) { 470 var value IPv6Mreq 471 vallen := _Socklen(SizeofIPv6Mreq) 472 err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen) 473 return &value, err 474 } 475 476 func SetsockoptInt(fd, level, opt int, value int) (err error) { 477 var n = int32(value) 478 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4) 479 } 480 481 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) { 482 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), 4) 483 } 484 485 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { 486 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(tv)), unsafe.Sizeof(*tv)) 487 } 488 489 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { 490 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(l)), unsafe.Sizeof(*l)) 491 } 492 493 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) { 494 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq)) 495 } 496 497 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { 498 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq)) 499 } 500 501 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) { 502 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq)) 503 } 504 505 func SetsockoptString(fd, level, opt int, s string) (err error) { 506 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&[]byte(s)[0])), uintptr(len(s))) 507 } 508 509 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { 510 var rsa RawSockaddrAny 511 var len _Socklen = SizeofSockaddrAny 512 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { 513 return 514 } 515 from, err = anyToSockaddr(&rsa) 516 return 517 } 518 519 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { 520 ptr, n, err := to.sockaddr() 521 if err != nil { 522 return err 523 } 524 return sendto(fd, p, flags, ptr, n) 525 } 526 527 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 528 var msg Msghdr 529 var rsa RawSockaddrAny 530 msg.Name = (*byte)(unsafe.Pointer(&rsa)) 531 msg.Namelen = uint32(SizeofSockaddrAny) 532 var iov Iovec 533 if len(p) > 0 { 534 iov.Base = (*byte)(unsafe.Pointer(&p[0])) 535 iov.SetLen(len(p)) 536 } 537 var dummy byte 538 if len(oob) > 0 { 539 // receive at least one normal byte 540 if len(p) == 0 { 541 iov.Base = &dummy 542 iov.SetLen(1) 543 } 544 msg.Control = (*byte)(unsafe.Pointer(&oob[0])) 545 msg.SetControllen(len(oob)) 546 } 547 msg.Iov = &iov 548 msg.Iovlen = 1 549 if n, err = recvmsg(fd, &msg, flags); err != nil { 550 return 551 } 552 oobn = int(msg.Controllen) 553 recvflags = int(msg.Flags) 554 // source address is only specified if the socket is unconnected 555 if rsa.Addr.Family != AF_UNSPEC { 556 from, err = anyToSockaddr(&rsa) 557 } 558 return 559 } 560 561 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 562 var ptr uintptr 563 var salen _Socklen 564 if to != nil { 565 var err error 566 ptr, salen, err = to.sockaddr() 567 if err != nil { 568 return err 569 } 570 } 571 var msg Msghdr 572 msg.Name = (*byte)(unsafe.Pointer(ptr)) 573 msg.Namelen = uint32(salen) 574 var iov Iovec 575 if len(p) > 0 { 576 iov.Base = (*byte)(unsafe.Pointer(&p[0])) 577 iov.SetLen(len(p)) 578 } 579 var dummy byte 580 if len(oob) > 0 { 581 // send at least one normal byte 582 if len(p) == 0 { 583 iov.Base = &dummy 584 iov.SetLen(1) 585 } 586 msg.Control = (*byte)(unsafe.Pointer(&oob[0])) 587 msg.SetControllen(len(oob)) 588 } 589 msg.Iov = &iov 590 msg.Iovlen = 1 591 if err = sendmsg(fd, &msg, flags); err != nil { 592 return 593 } 594 return 595 } 596 597 // BindToDevice binds the socket associated with fd to device. 598 func BindToDevice(fd int, device string) (err error) { 599 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device) 600 } 601 602 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) 603 604 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { 605 // The peek requests are machine-size oriented, so we wrap it 606 // to retrieve arbitrary-length data. 607 608 // The ptrace syscall differs from glibc's ptrace. 609 // Peeks returns the word in *data, not as the return value. 610 611 var buf [sizeofPtr]byte 612 613 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned 614 // access (PEEKUSER warns that it might), but if we don't 615 // align our reads, we might straddle an unmapped page 616 // boundary and not get the bytes leading up to the page 617 // boundary. 618 n := 0 619 if addr%sizeofPtr != 0 { 620 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 621 if err != nil { 622 return 0, err 623 } 624 n += copy(out, buf[addr%sizeofPtr:]) 625 out = out[n:] 626 } 627 628 // Remainder. 629 for len(out) > 0 { 630 // We use an internal buffer to guarantee alignment. 631 // It's not documented if this is necessary, but we're paranoid. 632 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 633 if err != nil { 634 return n, err 635 } 636 copied := copy(out, buf[0:]) 637 n += copied 638 out = out[copied:] 639 } 640 641 return n, nil 642 } 643 644 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { 645 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out) 646 } 647 648 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { 649 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out) 650 } 651 652 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) { 653 // As for ptracePeek, we need to align our accesses to deal 654 // with the possibility of straddling an invalid page. 655 656 // Leading edge. 657 n := 0 658 if addr%sizeofPtr != 0 { 659 var buf [sizeofPtr]byte 660 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 661 if err != nil { 662 return 0, err 663 } 664 n += copy(buf[addr%sizeofPtr:], data) 665 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 666 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word) 667 if err != nil { 668 return 0, err 669 } 670 data = data[n:] 671 } 672 673 // Interior. 674 for len(data) > sizeofPtr { 675 word := *((*uintptr)(unsafe.Pointer(&data[0]))) 676 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 677 if err != nil { 678 return n, err 679 } 680 n += sizeofPtr 681 data = data[sizeofPtr:] 682 } 683 684 // Trailing edge. 685 if len(data) > 0 { 686 var buf [sizeofPtr]byte 687 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 688 if err != nil { 689 return n, err 690 } 691 copy(buf[0:], data) 692 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 693 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 694 if err != nil { 695 return n, err 696 } 697 n += len(data) 698 } 699 700 return n, nil 701 } 702 703 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { 704 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data) 705 } 706 707 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { 708 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data) 709 } 710 711 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { 712 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) 713 } 714 715 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { 716 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) 717 } 718 719 func PtraceSetOptions(pid int, options int) (err error) { 720 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options)) 721 } 722 723 func PtraceGetEventMsg(pid int) (msg uint, err error) { 724 var data _C_long 725 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data))) 726 msg = uint(data) 727 return 728 } 729 730 func PtraceCont(pid int, signal int) (err error) { 731 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal)) 732 } 733 734 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } 735 736 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } 737 738 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } 739 740 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) 741 func Reboot(cmd int) (err error) { 742 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") 743 } 744 745 func clen(n []byte) int { 746 for i := 0; i < len(n); i++ { 747 if n[i] == 0 { 748 return i 749 } 750 } 751 return len(n) 752 } 753 754 func ReadDirent(fd int, buf []byte) (n int, err error) { 755 return Getdents(fd, buf) 756 } 757 758 func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { 759 origlen := len(buf) 760 count = 0 761 for max != 0 && len(buf) > 0 { 762 dirent := (*Dirent)(unsafe.Pointer(&buf[0])) 763 buf = buf[dirent.Reclen:] 764 if dirent.Ino == 0 { // File absent in directory. 765 continue 766 } 767 bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) 768 var name = string(bytes[0:clen(bytes[:])]) 769 if name == "." || name == ".." { // Useless names 770 continue 771 } 772 max-- 773 count++ 774 names = append(names, name) 775 } 776 return origlen - len(buf), count, names 777 } 778 779 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) 780 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { 781 // Certain file systems get rather angry and EINVAL if you give 782 // them an empty string of data, rather than NULL. 783 if data == "" { 784 return mount(source, target, fstype, flags, nil) 785 } 786 return mount(source, target, fstype, flags, StringBytePtr(data)) 787 } 788 789 // Sendto 790 // Recvfrom 791 // Socketpair 792 793 /* 794 * Direct access 795 */ 796 //sys Access(path string, mode uint32) (err error) 797 //sys Acct(path string) (err error) 798 //sys Adjtimex(buf *Timex) (state int, err error) 799 //sys Chdir(path string) (err error) 800 //sys Chmod(path string, mode uint32) (err error) 801 //sys Chroot(path string) (err error) 802 //sys Close(fd int) (err error) 803 //sys Creat(path string, mode uint32) (fd int, err error) 804 //sysnb Dup(oldfd int) (fd int, err error) 805 //sysnb Dup2(oldfd int, newfd int) (err error) 806 //sysnb EpollCreate(size int) (fd int, err error) 807 //sysnb EpollCreate1(flag int) (fd int, err error) 808 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) 809 //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) 810 //sys Exit(code int) = SYS_EXIT_GROUP 811 //sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) 812 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) 813 //sys Fchdir(fd int) (err error) 814 //sys Fchmod(fd int, mode uint32) (err error) 815 //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) 816 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 817 //sys fcntl(fd int, cmd int, arg int) (val int, err error) 818 //sys Fdatasync(fd int) (err error) 819 //sys Flock(fd int, how int) (err error) 820 //sys Fsync(fd int) (err error) 821 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 822 //sysnb Getpgid(pid int) (pgid int, err error) 823 //sysnb Getpgrp() (pid int) 824 //sysnb Getpid() (pid int) 825 //sysnb Getppid() (ppid int) 826 //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) 827 //sysnb Getrusage(who int, rusage *Rusage) (err error) 828 //sysnb Gettid() (tid int) 829 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) 830 //sysnb InotifyInit() (fd int, err error) 831 //sysnb InotifyInit1(flags int) (fd int, err error) 832 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) 833 //sysnb Kill(pid int, sig Signal) (err error) 834 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG 835 //sys Link(oldpath string, newpath string) (err error) 836 //sys Mkdir(path string, mode uint32) (err error) 837 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) 838 //sys Mknod(path string, mode uint32, dev int) (err error) 839 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) 840 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 841 //sys Pause() (err error) 842 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT 843 //sys Read(fd int, p []byte) (n int, err error) 844 //sys Readlink(path string, buf []byte) (n int, err error) 845 //sys Rename(oldpath string, newpath string) (err error) 846 //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) 847 //sys Rmdir(path string) (err error) 848 //sys Setdomainname(p []byte) (err error) 849 //sys Sethostname(p []byte) (err error) 850 //sysnb Setpgid(pid int, pgid int) (err error) 851 //sysnb Setrlimit(resource int, rlim *Rlimit) (err error) 852 //sysnb Setsid() (pid int, err error) 853 //sysnb Settimeofday(tv *Timeval) (err error) 854 //sysnb Setuid(uid int) (err error) 855 //sys Symlink(oldpath string, newpath string) (err error) 856 //sys Sync() 857 //sysnb Sysinfo(info *Sysinfo_t) (err error) 858 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) 859 //sysnb Tgkill(tgid int, tid int, sig Signal) (err error) 860 //sysnb Times(tms *Tms) (ticks uintptr, err error) 861 //sysnb Umask(mask int) (oldmask int) 862 //sysnb Uname(buf *Utsname) (err error) 863 //sys Unlink(path string) (err error) 864 //sys Unlinkat(dirfd int, path string) (err error) 865 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 866 //sys Unshare(flags int) (err error) 867 //sys Ustat(dev int, ubuf *Ustat_t) (err error) 868 //sys Utime(path string, buf *Utimbuf) (err error) 869 //sys Write(fd int, p []byte) (n int, err error) 870 //sys exitThread(code int) (err error) = SYS_EXIT 871 //sys read(fd int, p *byte, np int) (n int, err error) 872 //sys write(fd int, p *byte, np int) (n int, err error) 873 874 // mmap varies by architecture; see syscall_linux_*.go. 875 //sys munmap(addr uintptr, length uintptr) (err error) 876 877 var mapper = &mmapper{ 878 active: make(map[*byte][]byte), 879 mmap: mmap, 880 munmap: munmap, 881 } 882 883 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 884 return mapper.Mmap(fd, offset, length, prot, flags) 885 } 886 887 func Munmap(b []byte) (err error) { 888 return mapper.Munmap(b) 889 } 890 891 //sys Madvise(b []byte, advice int) (err error) 892 //sys Mprotect(b []byte, prot int) (err error) 893 //sys Mlock(b []byte) (err error) 894 //sys Munlock(b []byte) (err error) 895 //sys Mlockall(flags int) (err error) 896 //sys Munlockall() (err error) 897 898 /* 899 * Unimplemented 900 */ 901 // AddKey 902 // AfsSyscall 903 // Alarm 904 // ArchPrctl 905 // Brk 906 // Capget 907 // Capset 908 // ClockGetres 909 // ClockGettime 910 // ClockNanosleep 911 // ClockSettime 912 // Clone 913 // CreateModule 914 // DeleteModule 915 // EpollCtlOld 916 // EpollPwait 917 // EpollWaitOld 918 // Eventfd 919 // Execve 920 // Fadvise64 921 // Fgetxattr 922 // Flistxattr 923 // Fork 924 // Fremovexattr 925 // Fsetxattr 926 // Futex 927 // GetKernelSyms 928 // GetMempolicy 929 // GetRobustList 930 // GetThreadArea 931 // Getitimer 932 // Getpmsg 933 // Getpriority 934 // Getxattr 935 // IoCancel 936 // IoDestroy 937 // IoGetevents 938 // IoSetup 939 // IoSubmit 940 // Ioctl 941 // IoprioGet 942 // IoprioSet 943 // KexecLoad 944 // Keyctl 945 // Lgetxattr 946 // Listxattr 947 // Llistxattr 948 // LookupDcookie 949 // Lremovexattr 950 // Lsetxattr 951 // Mbind 952 // MigratePages 953 // Mincore 954 // ModifyLdt 955 // Mount 956 // MovePages 957 // Mprotect 958 // MqGetsetattr 959 // MqNotify 960 // MqOpen 961 // MqTimedreceive 962 // MqTimedsend 963 // MqUnlink 964 // Mremap 965 // Msgctl 966 // Msgget 967 // Msgrcv 968 // Msgsnd 969 // Msync 970 // Newfstatat 971 // Nfsservctl 972 // Personality 973 // Poll 974 // Ppoll 975 // Prctl 976 // Pselect6 977 // Ptrace 978 // Putpmsg 979 // QueryModule 980 // Quotactl 981 // Readahead 982 // Readv 983 // RemapFilePages 984 // Removexattr 985 // RequestKey 986 // RestartSyscall 987 // RtSigaction 988 // RtSigpending 989 // RtSigprocmask 990 // RtSigqueueinfo 991 // RtSigreturn 992 // RtSigsuspend 993 // RtSigtimedwait 994 // SchedGetPriorityMax 995 // SchedGetPriorityMin 996 // SchedGetaffinity 997 // SchedGetparam 998 // SchedGetscheduler 999 // SchedRrGetInterval 1000 // SchedSetaffinity 1001 // SchedSetparam 1002 // SchedYield 1003 // Security 1004 // Semctl 1005 // Semget 1006 // Semop 1007 // Semtimedop 1008 // SetMempolicy 1009 // SetRobustList 1010 // SetThreadArea 1011 // SetTidAddress 1012 // Setpriority 1013 // Setxattr 1014 // Shmat 1015 // Shmctl 1016 // Shmdt 1017 // Shmget 1018 // Sigaltstack 1019 // Signalfd 1020 // Swapoff 1021 // Swapon 1022 // Sysfs 1023 // TimerCreate 1024 // TimerDelete 1025 // TimerGetoverrun 1026 // TimerGettime 1027 // TimerSettime 1028 // Timerfd 1029 // Tkill (obsolete) 1030 // Tuxcall 1031 // Umount2 1032 // Uselib 1033 // Utimensat 1034 // Vfork 1035 // Vhangup 1036 // Vmsplice 1037 // Vserver 1038 // Waitid 1039 // Writev 1040 // _Sysctl