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

View as plain text