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