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