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 clen(n []byte) int {
    761 	for i := 0; i < len(n); i++ {
    762 		if n[i] == 0 {
    763 			return i
    764 		}
    765 	}
    766 	return len(n)
    767 }
    768 
    769 func ReadDirent(fd int, buf []byte) (n int, err error) {
    770 	return Getdents(fd, buf)
    771 }
    772 
    773 func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
    774 	origlen := len(buf)
    775 	count = 0
    776 	for max != 0 && len(buf) > 0 {
    777 		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
    778 		buf = buf[dirent.Reclen:]
    779 		if dirent.Ino == 0 { // File absent in directory.
    780 			continue
    781 		}
    782 		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
    783 		var name = string(bytes[0:clen(bytes[:])])
    784 		if name == "." || name == ".." { // Useless names
    785 			continue
    786 		}
    787 		max--
    788 		count++
    789 		names = append(names, name)
    790 	}
    791 	return origlen - len(buf), count, names
    792 }
    793 
    794 //sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
    795 
    796 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
    797 	// Certain file systems get rather angry and EINVAL if you give
    798 	// them an empty string of data, rather than NULL.
    799 	if data == "" {
    800 		return mount(source, target, fstype, flags, nil)
    801 	}
    802 	datap, err := BytePtrFromString(data)
    803 	if err != nil {
    804 		return err
    805 	}
    806 	err = mount(source, target, fstype, flags, datap)
    807 	use(unsafe.Pointer(datap))
    808 	return err
    809 }
    810 
    811 // Sendto
    812 // Recvfrom
    813 // Socketpair
    814 
    815 /*
    816  * Direct access
    817  */
    818 //sys	Acct(path string) (err error)
    819 //sys	Adjtimex(buf *Timex) (state int, err error)
    820 //sys	Chdir(path string) (err error)
    821 //sys	Chroot(path string) (err error)
    822 //sys	Close(fd int) (err error)
    823 //sys	Dup(oldfd int) (fd int, err error)
    824 //sys	Dup3(oldfd int, newfd int, flags int) (err error)
    825 //sysnb	EpollCreate(size int) (fd int, err error)
    826 //sysnb	EpollCreate1(flag int) (fd int, err error)
    827 //sysnb	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
    828 //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
    829 //sys	Exit(code int) = SYS_EXIT_GROUP
    830 //sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
    831 //sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
    832 //sys	Fchdir(fd int) (err error)
    833 //sys	Fchmod(fd int, mode uint32) (err error)
    834 //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
    835 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
    836 //sys	fcntl(fd int, cmd int, arg int) (val int, err error)
    837 //sys	Fdatasync(fd int) (err error)
    838 //sys	Flock(fd int, how int) (err error)
    839 //sys	Fsync(fd int) (err error)
    840 //sys	Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
    841 //sysnb	Getpgid(pid int) (pgid int, err error)
    842 
    843 func Getpgrp() (pid int) {
    844 	pid, _ = Getpgid(0)
    845 	return
    846 }
    847 
    848 //sysnb	Getpid() (pid int)
    849 //sysnb	Getppid() (ppid int)
    850 //sys	Getpriority(which int, who int) (prio int, err error)
    851 //sysnb	Getrusage(who int, rusage *Rusage) (err error)
    852 //sysnb	Gettid() (tid int)
    853 //sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
    854 //sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
    855 //sysnb	InotifyInit1(flags int) (fd int, err error)
    856 //sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
    857 //sysnb	Kill(pid int, sig Signal) (err error)
    858 //sys	Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
    859 //sys	Listxattr(path string, dest []byte) (sz int, err error)
    860 //sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
    861 //sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
    862 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
    863 //sys	Pause() (err error)
    864 //sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
    865 //sysnb prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) = SYS_PRLIMIT64
    866 //sys	read(fd int, p []byte) (n int, err error)
    867 //sys	Removexattr(path string, attr string) (err error)
    868 //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
    869 //sys	Setdomainname(p []byte) (err error)
    870 //sys	Sethostname(p []byte) (err error)
    871 //sysnb	Setpgid(pid int, pgid int) (err error)
    872 //sysnb	Setsid() (pid int, err error)
    873 //sysnb	Settimeofday(tv *Timeval) (err error)
    874 
    875 // issue 1435.
    876 // On linux Setuid and Setgid only affects the current thread, not the process.
    877 // This does not match what most callers expect so we must return an error
    878 // here rather than letting the caller think that the call succeeded.
    879 
    880 func Setuid(uid int) (err error) {
    881 	return EOPNOTSUPP
    882 }
    883 
    884 func Setgid(uid int) (err error) {
    885 	return EOPNOTSUPP
    886 }
    887 
    888 //sys	Setpriority(which int, who int, prio int) (err error)
    889 //sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
    890 //sys	Sync()
    891 //sysnb	Sysinfo(info *Sysinfo_t) (err error)
    892 //sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
    893 //sysnb	Tgkill(tgid int, tid int, sig Signal) (err error)
    894 //sysnb	Times(tms *Tms) (ticks uintptr, err error)
    895 //sysnb	Umask(mask int) (oldmask int)
    896 //sysnb	Uname(buf *Utsname) (err error)
    897 //sys	Unmount(target string, flags int) (err error) = SYS_UMOUNT2
    898 //sys	Unshare(flags int) (err error)
    899 //sys	Ustat(dev int, ubuf *Ustat_t) (err error)
    900 //sys	Utime(path string, buf *Utimbuf) (err error)
    901 //sys	write(fd int, p []byte) (n int, err error)
    902 //sys	exitThread(code int) (err error) = SYS_EXIT
    903 //sys	readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
    904 //sys	writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
    905 
    906 // mmap varies by architecture; see syscall_linux_*.go.
    907 //sys	munmap(addr uintptr, length uintptr) (err error)
    908 
    909 var mapper = &mmapper{
    910 	active: make(map[*byte][]byte),
    911 	mmap:   mmap,
    912 	munmap: munmap,
    913 }
    914 
    915 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
    916 	return mapper.Mmap(fd, offset, length, prot, flags)
    917 }
    918 
    919 func Munmap(b []byte) (err error) {
    920 	return mapper.Munmap(b)
    921 }
    922 
    923 //sys	Madvise(b []byte, advice int) (err error)
    924 //sys	Mprotect(b []byte, prot int) (err error)
    925 //sys	Mlock(b []byte) (err error)
    926 //sys	Munlock(b []byte) (err error)
    927 //sys	Mlockall(flags int) (err error)
    928 //sys	Munlockall() (err error)
    929 
    930 /*
    931  * Unimplemented
    932  */
    933 // AddKey
    934 // AfsSyscall
    935 // Alarm
    936 // ArchPrctl
    937 // Brk
    938 // Capget
    939 // Capset
    940 // ClockGetres
    941 // ClockGettime
    942 // ClockNanosleep
    943 // ClockSettime
    944 // Clone
    945 // CreateModule
    946 // DeleteModule
    947 // EpollCtlOld
    948 // EpollPwait
    949 // EpollWaitOld
    950 // Eventfd
    951 // Execve
    952 // Fadvise64
    953 // Fgetxattr
    954 // Flistxattr
    955 // Fork
    956 // Fremovexattr
    957 // Fsetxattr
    958 // Futex
    959 // GetKernelSyms
    960 // GetMempolicy
    961 // GetRobustList
    962 // GetThreadArea
    963 // Getitimer
    964 // Getpmsg
    965 // IoCancel
    966 // IoDestroy
    967 // IoGetevents
    968 // IoSetup
    969 // IoSubmit
    970 // Ioctl
    971 // IoprioGet
    972 // IoprioSet
    973 // KexecLoad
    974 // Keyctl
    975 // Lgetxattr
    976 // Llistxattr
    977 // LookupDcookie
    978 // Lremovexattr
    979 // Lsetxattr
    980 // Mbind
    981 // MigratePages
    982 // Mincore
    983 // ModifyLdt
    984 // Mount
    985 // MovePages
    986 // Mprotect
    987 // MqGetsetattr
    988 // MqNotify
    989 // MqOpen
    990 // MqTimedreceive
    991 // MqTimedsend
    992 // MqUnlink
    993 // Mremap
    994 // Msgctl
    995 // Msgget
    996 // Msgrcv
    997 // Msgsnd
    998 // Msync
    999 // Newfstatat
   1000 // Nfsservctl
   1001 // Personality
   1002 // Poll
   1003 // Ppoll
   1004 // Prctl
   1005 // Pselect6
   1006 // Ptrace
   1007 // Putpmsg
   1008 // QueryModule
   1009 // Quotactl
   1010 // Readahead
   1011 // Readv
   1012 // RemapFilePages
   1013 // RequestKey
   1014 // RestartSyscall
   1015 // RtSigaction
   1016 // RtSigpending
   1017 // RtSigprocmask
   1018 // RtSigqueueinfo
   1019 // RtSigreturn
   1020 // RtSigsuspend
   1021 // RtSigtimedwait
   1022 // SchedGetPriorityMax
   1023 // SchedGetPriorityMin
   1024 // SchedGetaffinity
   1025 // SchedGetparam
   1026 // SchedGetscheduler
   1027 // SchedRrGetInterval
   1028 // SchedSetaffinity
   1029 // SchedSetparam
   1030 // SchedYield
   1031 // Security
   1032 // Semctl
   1033 // Semget
   1034 // Semop
   1035 // Semtimedop
   1036 // SetMempolicy
   1037 // SetRobustList
   1038 // SetThreadArea
   1039 // SetTidAddress
   1040 // Shmat
   1041 // Shmctl
   1042 // Shmdt
   1043 // Shmget
   1044 // Sigaltstack
   1045 // Signalfd
   1046 // Swapoff
   1047 // Swapon
   1048 // Sysfs
   1049 // TimerCreate
   1050 // TimerDelete
   1051 // TimerGetoverrun
   1052 // TimerGettime
   1053 // TimerSettime
   1054 // Timerfd
   1055 // Tkill (obsolete)
   1056 // Tuxcall
   1057 // Umount2
   1058 // Uselib
   1059 // Utimensat
   1060 // Vfork
   1061 // Vhangup
   1062 // Vmsplice
   1063 // Vserver
   1064 // Waitid
   1065 // _Sysctl
   1066