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