github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/syscall/libcall_linux.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // GNU/Linux library calls.
     6  
     7  package syscall
     8  
     9  import "unsafe"
    10  
    11  //sys	Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
    12  //__go_openat(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int
    13  
    14  //sys	futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
    15  //futimesat(dirfd _C_int, path *byte, times *[2]Timeval) _C_int
    16  func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
    17  	if len(tv) != 2 {
    18  		return EINVAL
    19  	}
    20  	return futimesat(dirfd, StringBytePtr(path), (*[2]Timeval)(unsafe.Pointer(&tv[0])))
    21  }
    22  
    23  func Futimes(fd int, tv []Timeval) (err error) {
    24  	// Believe it or not, this is the best we can do on GNU/Linux
    25  	// (and is what glibc does).
    26  	return Utimes("/proc/self/fd/"+itoa(fd), tv)
    27  }
    28  
    29  //sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
    30  //ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
    31  
    32  //sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
    33  //ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
    34  
    35  func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
    36  	// The peek requests are machine-size oriented, so we wrap it
    37  	// to retrieve arbitrary-length data.
    38  
    39  	// The ptrace syscall differs from glibc's ptrace.
    40  	// Peeks returns the word in *data, not as the return value.
    41  
    42  	var buf [sizeofPtr]byte
    43  
    44  	// Leading edge.  PEEKTEXT/PEEKDATA don't require aligned
    45  	// access (PEEKUSER warns that it might), but if we don't
    46  	// align our reads, we might straddle an unmapped page
    47  	// boundary and not get the bytes leading up to the page
    48  	// boundary.
    49  	n := 0
    50  	if addr%sizeofPtr != 0 {
    51  		err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
    52  		if err != nil {
    53  			return 0, err
    54  		}
    55  		n += copy(out, buf[addr%sizeofPtr:])
    56  		out = out[n:]
    57  	}
    58  
    59  	// Remainder.
    60  	for len(out) > 0 {
    61  		// We use an internal buffer to gaurantee alignment.
    62  		// It's not documented if this is necessary, but we're paranoid.
    63  		err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
    64  		if err != nil {
    65  			return n, err
    66  		}
    67  		copied := copy(out, buf[0:])
    68  		n += copied
    69  		out = out[copied:]
    70  	}
    71  
    72  	return n, nil
    73  }
    74  
    75  func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
    76  	return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
    77  }
    78  
    79  func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
    80  	return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
    81  }
    82  
    83  func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
    84  	// As for ptracePeek, we need to align our accesses to deal
    85  	// with the possibility of straddling an invalid page.
    86  
    87  	// Leading edge.
    88  	n := 0
    89  	if addr%sizeofPtr != 0 {
    90  		var buf [sizeofPtr]byte
    91  		err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
    92  		if err != nil {
    93  			return 0, err
    94  		}
    95  		n += copy(buf[addr%sizeofPtr:], data)
    96  		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
    97  		err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
    98  		if err != nil {
    99  			return 0, err
   100  		}
   101  		data = data[n:]
   102  	}
   103  
   104  	// Interior.
   105  	for len(data) > int(sizeofPtr) {
   106  		word := *((*uintptr)(unsafe.Pointer(&data[0])))
   107  		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
   108  		if err != nil {
   109  			return n, err
   110  		}
   111  		n += int(sizeofPtr)
   112  		data = data[sizeofPtr:]
   113  	}
   114  
   115  	// Trailing edge.
   116  	if len(data) > 0 {
   117  		var buf [sizeofPtr]byte
   118  		err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
   119  		if err != nil {
   120  			return n, err
   121  		}
   122  		copy(buf[0:], data)
   123  		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
   124  		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
   125  		if err != nil {
   126  			return n, err
   127  		}
   128  		n += len(data)
   129  	}
   130  
   131  	return n, nil
   132  }
   133  
   134  func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
   135  	return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
   136  }
   137  
   138  func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
   139  	return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
   140  }
   141  
   142  func PtraceSetOptions(pid int, options int) (err error) {
   143  	return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
   144  }
   145  
   146  func PtraceGetEventMsg(pid int) (msg uint, err error) {
   147  	var data _C_long
   148  	err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
   149  	msg = uint(data)
   150  	return
   151  }
   152  
   153  func PtraceCont(pid int, signal int) (err error) {
   154  	return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
   155  }
   156  
   157  func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
   158  
   159  func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
   160  
   161  func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
   162  
   163  //sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
   164  //reboot(magic1 _C_uint, magic2 _C_uint, cmd _C_int, arg *byte) _C_int
   165  func Reboot(cmd int) (err error) {
   166  	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
   167  }
   168  
   169  //sys	accept4(fd int, sa *RawSockaddrAny, len *Socklen_t, flags int) (nfd int, err error)
   170  //accept4(fd _C_int, sa *RawSockaddrAny, len *Socklen_t, flags _C_int) _C_int
   171  
   172  func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
   173  	var rsa RawSockaddrAny
   174  	var len Socklen_t = SizeofSockaddrAny
   175  	nfd, err = accept4(fd, &rsa, &len, flags)
   176  	if err != nil {
   177  		return -1, nil, err
   178  	}
   179  	sa, err = anyToSockaddr(&rsa)
   180  	if err != nil {
   181  		Close(nfd)
   182  		return -1, nil, err
   183  	}
   184  	return nfd, sa, nil
   185  }
   186  
   187  //sys	Acct(path string) (err error)
   188  //acct(path *byte) _C_int
   189  
   190  //sys	Adjtimex(buf *Timex) (state int, err error)
   191  //adjtimex(buf *Timex) _C_int
   192  
   193  //sysnb	Dup3(oldfd int, newfd int, flags int) (err error)
   194  //dup3(oldfd _C_int, newfd _C_int, flags _C_int) _C_int
   195  
   196  //sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
   197  //faccessat(dirfd _C_int, pathname *byte, mode _C_int, flags _C_int) _C_int
   198  
   199  //sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
   200  //fallocate(fd _C_int, mode _C_int, offset Offset_t, len Offset_t) _C_int
   201  
   202  //sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
   203  //fchmodat(dirfd _C_int, pathname *byte, mode Mode_t, flags _C_int) _C_int
   204  
   205  //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
   206  //fchownat(dirfd _C_int, path *byte, owner Uid_t, group Gid_t, flags _C_int) _C_int
   207  
   208  //sys	Flock(fd int, how int) (err error)
   209  //flock(fd _C_int, how _C_int) _C_int
   210  
   211  //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
   212  //fstatfs(fd _C_int, buf *Statfs_t) _C_int
   213  
   214  func Gettid() (tid int) {
   215  	r1, _, _ := Syscall(SYS_GETTID, 0, 0, 0)
   216  	return int(r1)
   217  }
   218  
   219  func Getdents(fd int, buf []byte) (n int, err error) {
   220  	var p *byte
   221  	if len(buf) > 0 {
   222  		p = &buf[0]
   223  	} else {
   224  		p = (*byte)(unsafe.Pointer(&_zero))
   225  	}
   226  	s := SYS_GETDENTS64
   227  	if s == 0 {
   228  		s = SYS_GETDENTS
   229  	}
   230  	r1, _, errno := Syscall(uintptr(s), uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(len(buf)))
   231  	n = int(r1)
   232  	if n < 0 {
   233  		err = errno
   234  	}
   235  	return
   236  }
   237  
   238  func clen(n []byte) int {
   239  	for i := 0; i < len(n); i++ {
   240  		if n[i] == 0 {
   241  			return i
   242  		}
   243  	}
   244  	return len(n)
   245  }
   246  
   247  func ReadDirent(fd int, buf []byte) (n int, err error) {
   248  	return Getdents(fd, buf)
   249  }
   250  
   251  func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
   252  	origlen := len(buf)
   253  	count = 0
   254  	for max != 0 && len(buf) > 0 {
   255  		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
   256  		buf = buf[dirent.Reclen:]
   257  		if dirent.Ino == 0 { // File absent in directory.
   258  			continue
   259  		}
   260  		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
   261  		var name = string(bytes[0:clen(bytes[:])])
   262  		if name == "." || name == ".." { // Useless names
   263  			continue
   264  		}
   265  		max--
   266  		count++
   267  		names = append(names, name)
   268  	}
   269  	return origlen - len(buf), count, names
   270  }
   271  
   272  //sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
   273  //getxattr(path *byte, attr *byte, buf *byte, count Size_t) Ssize_t
   274  
   275  //sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
   276  //inotify_add_watch(fd _C_int, pathname *byte, mask uint32) _C_int
   277  
   278  //sysnb	InotifyInit() (fd int, err error)
   279  //inotify_init() _C_int
   280  
   281  //sysnb	InotifyInit1(flags int) (fd int, err error)
   282  //inotify_init1(flags _C_int) _C_int
   283  
   284  //sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
   285  //inotify_rm_watch(fd _C_int, wd uint32) _C_int
   286  
   287  //sys	Klogctl(typ int, buf []byte) (n int, err error)
   288  //klogctl(typ _C_int, bufp *byte, len _C_int) _C_int
   289  
   290  //sys	Listxattr(path string, dest []byte) (sz int, err error)
   291  //listxattr(path *byte, list *byte, size Size_t) Ssize_t
   292  
   293  //sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
   294  //mkdirat(dirfd _C_int, path *byte, mode Mode_t) _C_int
   295  
   296  //sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
   297  //mknodat(dirfd _C_int, path *byte, mode Mode_t, dev _dev_t) _C_int
   298  
   299  //sysnb	pipe2(p *[2]_C_int, flags int) (err error)
   300  //pipe2(p *[2]_C_int, flags _C_int) _C_int
   301  func Pipe2(p []int, flags int) (err error) {
   302  	if len(p) != 2 {
   303  		return EINVAL
   304  	}
   305  	var pp [2]_C_int
   306  	err = pipe2(&pp, flags)
   307  	p[0] = int(pp[0])
   308  	p[1] = int(pp[1])
   309  	return
   310  }
   311  
   312  //sys	PivotRoot(newroot string, putold string) (err error)
   313  //pivot_root(newroot *byte, putold *byte) _C_int
   314  
   315  //sys	Removexattr(path string, attr string) (err error)
   316  //removexattr(path *byte, name *byte) _C_int
   317  
   318  //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
   319  //renameat(olddirfd _C_int, oldpath *byte, newdirfd _C_int, newpath *byte) _C_int
   320  
   321  //sys	sendfile(outfd int, infd int, offset *Offset_t, count int) (written int, err error)
   322  //sendfile64(outfd _C_int, infd _C_int, offset *Offset_t, count Size_t) Ssize_t
   323  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
   324  	if raceenabled {
   325  		raceReleaseMerge(unsafe.Pointer(&ioSync))
   326  	}
   327  	var soff Offset_t
   328  	var psoff *Offset_t
   329  	if offset != nil {
   330  		soff = Offset_t(*offset)
   331  		psoff = &soff
   332  	}
   333  	written, err = sendfile(outfd, infd, psoff, count)
   334  	if offset != nil {
   335  		*offset = int64(soff)
   336  	}
   337  	return
   338  }
   339  
   340  //sys	Setfsgid(gid int) (err error)
   341  //setfsgid(gid Gid_t) _C_int
   342  
   343  //sys	Setfsuid(uid int) (err error)
   344  //setfsuid(uid Uid_t) _C_int
   345  
   346  //sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
   347  //setresgid(rgid Gid_t, egid Gid_t, sgid Gid_t) _C_int
   348  
   349  //sysnb	Setresuid(ruid int, eguid int, suid int) (err error)
   350  //setresuid(ruid Uid_t, euid Uid_t, suid Uid_t) _C_int
   351  
   352  //sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
   353  //setxattr(path *byte, name *byte, value *byte, size Size_t, flags _C_int) _C_int
   354  
   355  //sys	splice(rfd int, roff *_loff_t, wfd int, woff *_loff_t, len int, flags int) (n int64, err error)
   356  //splice(rfd _C_int, roff *_loff_t, wfd _C_int, woff *_loff_t, len Size_t, flags _C_uint) Ssize_t
   357  func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
   358  	var lroff _loff_t
   359  	var plroff *_loff_t
   360  	if roff != nil {
   361  		lroff = _loff_t(*roff)
   362  		plroff = &lroff
   363  	}
   364  	var lwoff _loff_t
   365  	var plwoff *_loff_t
   366  	if woff != nil {
   367  		lwoff = _loff_t(*woff)
   368  		plwoff = &lwoff
   369  	}
   370  	n, err = splice(rfd, plroff, wfd, plwoff, len, flags)
   371  	if roff != nil {
   372  		*roff = int64(lroff)
   373  	}
   374  	if woff != nil {
   375  		*woff = int64(lwoff)
   376  	}
   377  	return
   378  }
   379  
   380  //sys	Statfs(path string, buf *Statfs_t) (err error)
   381  //statfs(path *byte, buf *Statfs_t) _C_int
   382  
   383  //sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
   384  //sync_file_range(fd _C_int, off Offset_t, n Offset_t, flags _C_uint) _C_int
   385  
   386  //sysnb	Sysinfo(info *Sysinfo_t) (err error)
   387  //sysinfo(info *Sysinfo_t) _C_int
   388  
   389  //sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
   390  //tee(rfd _C_int, wfd _C_int, len Size_t, flags _C_uint) Ssize_t
   391  
   392  func Tgkill(tgid int, tid int, sig Signal) error {
   393  	r1, _, errno := Syscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
   394  	if r1 < 0 {
   395  		return errno
   396  	}
   397  	return nil
   398  }
   399  
   400  //sys	unlinkat(dirfd int, path string, flags int) (err error)
   401  //unlinkat(dirfd _C_int, path *byte, flags _C_int) _C_int
   402  
   403  func Unlinkat(dirfd int, path string) (err error) {
   404  	return unlinkat(dirfd, path, 0)
   405  }
   406  
   407  //sys	Unmount(target string, flags int) (err error) = SYS_UMOUNT2
   408  //umount2(target *byte, flags _C_int) _C_int
   409  
   410  //sys	Unshare(flags int) (err error)
   411  //unshare(flags _C_int) _C_int