github.com/euank/go@v0.0.0-20160829210321-495514729181/src/syscall/syscall_linux_386.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  // TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
     6  // so that go vet can check that they are correct.
     7  
     8  package syscall
     9  
    10  import "unsafe"
    11  
    12  const (
    13  	_SYS_dup      = SYS_DUP2
    14  	_SYS_getdents = SYS_GETDENTS64
    15  )
    16  
    17  func Getpagesize() int { return 4096 }
    18  
    19  func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
    20  
    21  func NsecToTimespec(nsec int64) (ts Timespec) {
    22  	ts.Sec = int32(nsec / 1e9)
    23  	ts.Nsec = int32(nsec % 1e9)
    24  	return
    25  }
    26  
    27  func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
    28  
    29  func NsecToTimeval(nsec int64) (tv Timeval) {
    30  	nsec += 999 // round up to microsecond
    31  	tv.Sec = int32(nsec / 1e9)
    32  	tv.Usec = int32(nsec % 1e9 / 1e3)
    33  	return
    34  }
    35  
    36  //sysnb	pipe(p *[2]_C_int) (err error)
    37  
    38  func Pipe(p []int) (err error) {
    39  	if len(p) != 2 {
    40  		return EINVAL
    41  	}
    42  	var pp [2]_C_int
    43  	err = pipe(&pp)
    44  	p[0] = int(pp[0])
    45  	p[1] = int(pp[1])
    46  	return
    47  }
    48  
    49  //sysnb pipe2(p *[2]_C_int, flags int) (err error)
    50  
    51  func Pipe2(p []int, flags int) (err error) {
    52  	if len(p) != 2 {
    53  		return EINVAL
    54  	}
    55  	var pp [2]_C_int
    56  	err = pipe2(&pp, flags)
    57  	p[0] = int(pp[0])
    58  	p[1] = int(pp[1])
    59  	return
    60  }
    61  
    62  // 64-bit file system and 32-bit uid calls
    63  // (386 default is 32-bit file system and 16-bit uid).
    64  //sys	Dup2(oldfd int, newfd int) (err error)
    65  //sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
    66  //sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
    67  //sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
    68  //sysnb	Getegid() (egid int) = SYS_GETEGID32
    69  //sysnb	Geteuid() (euid int) = SYS_GETEUID32
    70  //sysnb	Getgid() (gid int) = SYS_GETGID32
    71  //sysnb	Getuid() (uid int) = SYS_GETUID32
    72  //sysnb	InotifyInit() (fd int, err error)
    73  //sys	Ioperm(from int, num int, on int) (err error)
    74  //sys	Iopl(level int) (err error)
    75  //sys	Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
    76  //sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
    77  //sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
    78  //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
    79  //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
    80  //sys	Setfsgid(gid int) (err error) = SYS_SETFSGID32
    81  //sys	Setfsuid(uid int) (err error) = SYS_SETFSUID32
    82  //sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
    83  //sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
    84  //sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
    85  //sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
    86  //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
    87  //sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
    88  //sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
    89  //sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
    90  //sysnb	getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
    91  //sysnb	setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
    92  //sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
    93  
    94  //sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
    95  
    96  func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
    97  	page := uintptr(offset / 4096)
    98  	if offset != int64(page)*4096 {
    99  		return 0, EINVAL
   100  	}
   101  	return mmap2(addr, length, prot, flags, fd, page)
   102  }
   103  
   104  type rlimit32 struct {
   105  	Cur uint32
   106  	Max uint32
   107  }
   108  
   109  //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
   110  
   111  const rlimInf32 = ^uint32(0)
   112  const rlimInf64 = ^uint64(0)
   113  
   114  func Getrlimit(resource int, rlim *Rlimit) (err error) {
   115  	err = prlimit(0, resource, nil, rlim)
   116  	if err != ENOSYS {
   117  		return err
   118  	}
   119  
   120  	rl := rlimit32{}
   121  	err = getrlimit(resource, &rl)
   122  	if err != nil {
   123  		return
   124  	}
   125  
   126  	if rl.Cur == rlimInf32 {
   127  		rlim.Cur = rlimInf64
   128  	} else {
   129  		rlim.Cur = uint64(rl.Cur)
   130  	}
   131  
   132  	if rl.Max == rlimInf32 {
   133  		rlim.Max = rlimInf64
   134  	} else {
   135  		rlim.Max = uint64(rl.Max)
   136  	}
   137  	return
   138  }
   139  
   140  //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
   141  
   142  func Setrlimit(resource int, rlim *Rlimit) (err error) {
   143  	err = prlimit(0, resource, rlim, nil)
   144  	if err != ENOSYS {
   145  		return err
   146  	}
   147  
   148  	rl := rlimit32{}
   149  	if rlim.Cur == rlimInf64 {
   150  		rl.Cur = rlimInf32
   151  	} else if rlim.Cur < uint64(rlimInf32) {
   152  		rl.Cur = uint32(rlim.Cur)
   153  	} else {
   154  		return EINVAL
   155  	}
   156  	if rlim.Max == rlimInf64 {
   157  		rl.Max = rlimInf32
   158  	} else if rlim.Max < uint64(rlimInf32) {
   159  		rl.Max = uint32(rlim.Max)
   160  	} else {
   161  		return EINVAL
   162  	}
   163  
   164  	return setrlimit(resource, &rl)
   165  }
   166  
   167  // Underlying system call writes to newoffset via pointer.
   168  // Implemented in assembly to avoid allocation.
   169  func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
   170  
   171  func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
   172  	newoffset, errno := seek(fd, offset, whence)
   173  	if errno != 0 {
   174  		return 0, errno
   175  	}
   176  	return newoffset, nil
   177  }
   178  
   179  // Vsyscalls on amd64.
   180  //sysnb	Gettimeofday(tv *Timeval) (err error)
   181  //sysnb	Time(t *Time_t) (tt Time_t, err error)
   182  
   183  // On x86 Linux, all the socket calls go through an extra indirection,
   184  // I think because the 5-register system call interface can't handle
   185  // the 6-argument calls like sendto and recvfrom. Instead the
   186  // arguments to the underlying system call are the number below
   187  // and a pointer to an array of uintptr. We hide the pointer in the
   188  // socketcall assembly to avoid allocation on every system call.
   189  
   190  const (
   191  	// see linux/net.h
   192  	_SOCKET      = 1
   193  	_BIND        = 2
   194  	_CONNECT     = 3
   195  	_LISTEN      = 4
   196  	_ACCEPT      = 5
   197  	_GETSOCKNAME = 6
   198  	_GETPEERNAME = 7
   199  	_SOCKETPAIR  = 8
   200  	_SEND        = 9
   201  	_RECV        = 10
   202  	_SENDTO      = 11
   203  	_RECVFROM    = 12
   204  	_SHUTDOWN    = 13
   205  	_SETSOCKOPT  = 14
   206  	_GETSOCKOPT  = 15
   207  	_SENDMSG     = 16
   208  	_RECVMSG     = 17
   209  	_ACCEPT4     = 18
   210  	_RECVMMSG    = 19
   211  	_SENDMMSG    = 20
   212  )
   213  
   214  func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
   215  func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
   216  
   217  func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
   218  	fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   219  	if e != 0 {
   220  		err = e
   221  	}
   222  	return
   223  }
   224  
   225  func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
   226  	fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
   227  	if e != 0 {
   228  		err = e
   229  	}
   230  	return
   231  }
   232  
   233  func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
   234  	_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   235  	if e != 0 {
   236  		err = e
   237  	}
   238  	return
   239  }
   240  
   241  func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
   242  	_, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   243  	if e != 0 {
   244  		err = e
   245  	}
   246  	return
   247  }
   248  
   249  func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
   250  	_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
   251  	if e != 0 {
   252  		err = e
   253  	}
   254  	return
   255  }
   256  
   257  func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
   258  	_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
   259  	if e != 0 {
   260  		err = e
   261  	}
   262  	return
   263  }
   264  
   265  func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
   266  	_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
   267  	if e != 0 {
   268  		err = e
   269  	}
   270  	return
   271  }
   272  
   273  func socket(domain int, typ int, proto int) (fd int, err error) {
   274  	fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
   275  	if e != 0 {
   276  		err = e
   277  	}
   278  	return
   279  }
   280  
   281  func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
   282  	_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
   283  	if e != 0 {
   284  		err = e
   285  	}
   286  	return
   287  }
   288  
   289  func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
   290  	_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
   291  	if e != 0 {
   292  		err = e
   293  	}
   294  	return
   295  }
   296  
   297  func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
   298  	var base uintptr
   299  	if len(p) > 0 {
   300  		base = uintptr(unsafe.Pointer(&p[0]))
   301  	}
   302  	n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
   303  	if e != 0 {
   304  		err = e
   305  	}
   306  	return
   307  }
   308  
   309  func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
   310  	var base uintptr
   311  	if len(p) > 0 {
   312  		base = uintptr(unsafe.Pointer(&p[0]))
   313  	}
   314  	_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))
   315  	if e != 0 {
   316  		err = e
   317  	}
   318  	return
   319  }
   320  
   321  func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
   322  	n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
   323  	if e != 0 {
   324  		err = e
   325  	}
   326  	return
   327  }
   328  
   329  func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
   330  	n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
   331  	if e != 0 {
   332  		err = e
   333  	}
   334  	return
   335  }
   336  
   337  func Listen(s int, n int) (err error) {
   338  	_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
   339  	if e != 0 {
   340  		err = e
   341  	}
   342  	return
   343  }
   344  
   345  func Shutdown(s, how int) (err error) {
   346  	_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
   347  	if e != 0 {
   348  		err = e
   349  	}
   350  	return
   351  }
   352  
   353  func Fstatfs(fd int, buf *Statfs_t) (err error) {
   354  	_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
   355  	if e != 0 {
   356  		err = e
   357  	}
   358  	return
   359  }
   360  
   361  func Statfs(path string, buf *Statfs_t) (err error) {
   362  	pathp, err := BytePtrFromString(path)
   363  	if err != nil {
   364  		return err
   365  	}
   366  	_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
   367  	use(unsafe.Pointer(pathp))
   368  	if e != 0 {
   369  		err = e
   370  	}
   371  	return
   372  }
   373  
   374  func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
   375  
   376  func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
   377  
   378  func (iov *Iovec) SetLen(length int) {
   379  	iov.Len = uint32(length)
   380  }
   381  
   382  func (msghdr *Msghdr) SetControllen(length int) {
   383  	msghdr.Controllen = uint32(length)
   384  }
   385  
   386  func (cmsg *Cmsghdr) SetLen(length int) {
   387  	cmsg.Len = uint32(length)
   388  }