Source file src/syscall/syscall_linux_386.go

     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  package syscall
     6  
     7  import "unsafe"
     8  
     9  const _SYS_setgroups = SYS_SETGROUPS32
    10  
    11  func setTimespec(sec, nsec int64) Timespec {
    12  	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
    13  }
    14  
    15  func setTimeval(sec, usec int64) Timeval {
    16  	return Timeval{Sec: int32(sec), Usec: int32(usec)}
    17  }
    18  
    19  // 64-bit file system and 32-bit uid calls
    20  // (386 default is 32-bit file system and 16-bit uid).
    21  //sys	Dup2(oldfd int, newfd int) (err error)
    22  //sysnb	EpollCreate(size int) (fd int, err error)
    23  //sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
    24  //sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
    25  //sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
    26  //sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
    27  //sysnb	Getegid() (egid int) = SYS_GETEGID32
    28  //sysnb	Geteuid() (euid int) = SYS_GETEUID32
    29  //sysnb	Getgid() (gid int) = SYS_GETGID32
    30  //sysnb	Getuid() (uid int) = SYS_GETUID32
    31  //sysnb	InotifyInit() (fd int, err error)
    32  //sys	Ioperm(from int, num int, on int) (err error)
    33  //sys	Iopl(level int) (err error)
    34  //sys	Pause() (err error)
    35  //sys	pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
    36  //sys	pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
    37  //sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
    38  //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
    39  //sys	Setfsgid(gid int) (err error) = SYS_SETFSGID32
    40  //sys	Setfsuid(uid int) (err error) = SYS_SETFSUID32
    41  //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
    42  //sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
    43  //sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
    44  //sys	Ustat(dev int, ubuf *Ustat_t) (err error)
    45  //sysnb	getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
    46  //sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
    47  
    48  //sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
    49  //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
    50  
    51  func Stat(path string, stat *Stat_t) (err error) {
    52  	return fstatat(_AT_FDCWD, path, stat, 0)
    53  }
    54  
    55  func Lchown(path string, uid int, gid int) (err error) {
    56  	return Fchownat(_AT_FDCWD, path, uid, gid, _AT_SYMLINK_NOFOLLOW)
    57  }
    58  
    59  func Lstat(path string, stat *Stat_t) (err error) {
    60  	return fstatat(_AT_FDCWD, path, stat, _AT_SYMLINK_NOFOLLOW)
    61  }
    62  
    63  func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
    64  	page := uintptr(offset / 4096)
    65  	if offset != int64(page)*4096 {
    66  		return 0, EINVAL
    67  	}
    68  	return mmap2(addr, length, prot, flags, fd, page)
    69  }
    70  
    71  type rlimit32 struct {
    72  	Cur uint32
    73  	Max uint32
    74  }
    75  
    76  //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
    77  
    78  const rlimInf32 = ^uint32(0)
    79  const rlimInf64 = ^uint64(0)
    80  
    81  func Getrlimit(resource int, rlim *Rlimit) (err error) {
    82  	err = prlimit(0, resource, nil, rlim)
    83  	if err != ENOSYS {
    84  		return err
    85  	}
    86  
    87  	rl := rlimit32{}
    88  	err = getrlimit(resource, &rl)
    89  	if err != nil {
    90  		return
    91  	}
    92  
    93  	if rl.Cur == rlimInf32 {
    94  		rlim.Cur = rlimInf64
    95  	} else {
    96  		rlim.Cur = uint64(rl.Cur)
    97  	}
    98  
    99  	if rl.Max == rlimInf32 {
   100  		rlim.Max = rlimInf64
   101  	} else {
   102  		rlim.Max = uint64(rl.Max)
   103  	}
   104  	return
   105  }
   106  
   107  //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
   108  
   109  func Setrlimit(resource int, rlim *Rlimit) (err error) {
   110  	err = prlimit(0, resource, rlim, nil)
   111  	if err != ENOSYS {
   112  		return err
   113  	}
   114  
   115  	rl := rlimit32{}
   116  	if rlim.Cur == rlimInf64 {
   117  		rl.Cur = rlimInf32
   118  	} else if rlim.Cur < uint64(rlimInf32) {
   119  		rl.Cur = uint32(rlim.Cur)
   120  	} else {
   121  		return EINVAL
   122  	}
   123  	if rlim.Max == rlimInf64 {
   124  		rl.Max = rlimInf32
   125  	} else if rlim.Max < uint64(rlimInf32) {
   126  		rl.Max = uint32(rlim.Max)
   127  	} else {
   128  		return EINVAL
   129  	}
   130  
   131  	return setrlimit(resource, &rl)
   132  }
   133  
   134  // Underlying system call writes to newoffset via pointer.
   135  // Implemented in assembly to avoid allocation.
   136  func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
   137  
   138  func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
   139  	newoffset, errno := seek(fd, offset, whence)
   140  	if errno != 0 {
   141  		return 0, errno
   142  	}
   143  	return newoffset, nil
   144  }
   145  
   146  //sys	futimesat(dirfd int, path string, times *[2]Timeval) (err error)
   147  //sysnb	Gettimeofday(tv *Timeval) (err error)
   148  //sysnb	Time(t *Time_t) (tt Time_t, err error)
   149  //sys	Utime(path string, buf *Utimbuf) (err error)
   150  //sys	utimes(path string, times *[2]Timeval) (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 accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
   187  	fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
   188  	if e != 0 {
   189  		err = e
   190  	}
   191  	return
   192  }
   193  
   194  func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
   195  	_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   196  	if e != 0 {
   197  		err = e
   198  	}
   199  	return
   200  }
   201  
   202  func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
   203  	_, e := rawsocketcall(_GETPEERNAME, 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 socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
   211  	_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
   212  	if e != 0 {
   213  		err = e
   214  	}
   215  	return
   216  }
   217  
   218  func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
   219  	_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
   220  	if e != 0 {
   221  		err = e
   222  	}
   223  	return
   224  }
   225  
   226  func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
   227  	_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
   228  	if e != 0 {
   229  		err = e
   230  	}
   231  	return
   232  }
   233  
   234  func socket(domain int, typ int, proto int) (fd int, err error) {
   235  	fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
   236  	if e != 0 {
   237  		err = e
   238  	}
   239  	return
   240  }
   241  
   242  func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
   243  	_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
   244  	if e != 0 {
   245  		err = e
   246  	}
   247  	return
   248  }
   249  
   250  func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
   251  	_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
   252  	if e != 0 {
   253  		err = e
   254  	}
   255  	return
   256  }
   257  
   258  func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
   259  	var base uintptr
   260  	if len(p) > 0 {
   261  		base = uintptr(unsafe.Pointer(&p[0]))
   262  	}
   263  	n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
   264  	if e != 0 {
   265  		err = e
   266  	}
   267  	return
   268  }
   269  
   270  func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
   271  	var base uintptr
   272  	if len(p) > 0 {
   273  		base = uintptr(unsafe.Pointer(&p[0]))
   274  	}
   275  	_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))
   276  	if e != 0 {
   277  		err = e
   278  	}
   279  	return
   280  }
   281  
   282  func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
   283  	n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
   284  	if e != 0 {
   285  		err = e
   286  	}
   287  	return
   288  }
   289  
   290  func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
   291  	n, e := socketcall(_SENDMSG, 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 Listen(s int, n int) (err error) {
   299  	_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
   300  	if e != 0 {
   301  		err = e
   302  	}
   303  	return
   304  }
   305  
   306  func Shutdown(s, how int) (err error) {
   307  	_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
   308  	if e != 0 {
   309  		err = e
   310  	}
   311  	return
   312  }
   313  
   314  func Fstatfs(fd int, buf *Statfs_t) (err error) {
   315  	_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
   316  	if e != 0 {
   317  		err = e
   318  	}
   319  	return
   320  }
   321  
   322  func Statfs(path string, buf *Statfs_t) (err error) {
   323  	pathp, err := BytePtrFromString(path)
   324  	if err != nil {
   325  		return err
   326  	}
   327  	_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
   328  	if e != 0 {
   329  		err = e
   330  	}
   331  	return
   332  }
   333  
   334  func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
   335  
   336  func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
   337  
   338  func (iov *Iovec) SetLen(length int) {
   339  	iov.Len = uint32(length)
   340  }
   341  
   342  func (msghdr *Msghdr) SetControllen(length int) {
   343  	msghdr.Controllen = uint32(length)
   344  }
   345  
   346  func (cmsg *Cmsghdr) SetLen(length int) {
   347  	cmsg.Len = uint32(length)
   348  }
   349  
   350  func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
   351  

View as plain text