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