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