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

View as plain text