github.com/dorkamotorka/go/src@v0.0.0-20230614113921-187095f0e316/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  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 setrlimit1(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 setrlimit1(resource, &rl)
   135  }
   136  
   137  //go:nosplit
   138  func rawSetrlimit(resource int, rlim *Rlimit) Errno {
   139  	_, _, errno := RawSyscall6(SYS_PRLIMIT64, 0, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0, 0, 0)
   140  	if errno != ENOSYS {
   141  		return errno
   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  	_, _, errno = RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
   161  	return errno
   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  //sys	futimesat(dirfd int, path string, times *[2]Timeval) (err error)
   177  //sysnb	Gettimeofday(tv *Timeval) (err error)
   178  //sysnb	Time(t *Time_t) (tt Time_t, err error)
   179  //sys	Utime(path string, buf *Utimbuf) (err error)
   180  //sys	utimes(path string, times *[2]Timeval) (err error)
   181  
   182  // On x86 Linux, all the socket calls go through an extra indirection,
   183  // I think because the 5-register system call interface can't handle
   184  // the 6-argument calls like sendto and recvfrom. Instead the
   185  // arguments to the underlying system call are the number below
   186  // and a pointer to an array of uintptr. We hide the pointer in the
   187  // socketcall assembly to avoid allocation on every system call.
   188  
   189  const (
   190  	// see linux/net.h
   191  	_SOCKET      = 1
   192  	_BIND        = 2
   193  	_CONNECT     = 3
   194  	_LISTEN      = 4
   195  	_ACCEPT      = 5
   196  	_GETSOCKNAME = 6
   197  	_GETPEERNAME = 7
   198  	_SOCKETPAIR  = 8
   199  	_SEND        = 9
   200  	_RECV        = 10
   201  	_SENDTO      = 11
   202  	_RECVFROM    = 12
   203  	_SHUTDOWN    = 13
   204  	_SETSOCKOPT  = 14
   205  	_GETSOCKOPT  = 15
   206  	_SENDMSG     = 16
   207  	_RECVMSG     = 17
   208  	_ACCEPT4     = 18
   209  	_RECVMMSG    = 19
   210  	_SENDMMSG    = 20
   211  )
   212  
   213  func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
   214  func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
   215  
   216  func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
   217  	fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
   218  	if e != 0 {
   219  		err = e
   220  	}
   221  	return
   222  }
   223  
   224  func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
   225  	_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   226  	if e != 0 {
   227  		err = e
   228  	}
   229  	return
   230  }
   231  
   232  func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
   233  	_, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   234  	if e != 0 {
   235  		err = e
   236  	}
   237  	return
   238  }
   239  
   240  func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
   241  	_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
   242  	if e != 0 {
   243  		err = e
   244  	}
   245  	return
   246  }
   247  
   248  func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
   249  	_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
   250  	if e != 0 {
   251  		err = e
   252  	}
   253  	return
   254  }
   255  
   256  func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
   257  	_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
   258  	if e != 0 {
   259  		err = e
   260  	}
   261  	return
   262  }
   263  
   264  func socket(domain int, typ int, proto int) (fd int, err error) {
   265  	fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
   266  	if e != 0 {
   267  		err = e
   268  	}
   269  	return
   270  }
   271  
   272  func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
   273  	_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
   274  	if e != 0 {
   275  		err = e
   276  	}
   277  	return
   278  }
   279  
   280  func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
   281  	_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
   282  	if e != 0 {
   283  		err = e
   284  	}
   285  	return
   286  }
   287  
   288  func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
   289  	var base uintptr
   290  	if len(p) > 0 {
   291  		base = uintptr(unsafe.Pointer(&p[0]))
   292  	}
   293  	n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
   294  	if e != 0 {
   295  		err = e
   296  	}
   297  	return
   298  }
   299  
   300  func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
   301  	var base uintptr
   302  	if len(p) > 0 {
   303  		base = uintptr(unsafe.Pointer(&p[0]))
   304  	}
   305  	_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))
   306  	if e != 0 {
   307  		err = e
   308  	}
   309  	return
   310  }
   311  
   312  func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
   313  	n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
   314  	if e != 0 {
   315  		err = e
   316  	}
   317  	return
   318  }
   319  
   320  func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
   321  	n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
   322  	if e != 0 {
   323  		err = e
   324  	}
   325  	return
   326  }
   327  
   328  func Listen(s int, n int) (err error) {
   329  	_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
   330  	if e != 0 {
   331  		err = e
   332  	}
   333  	return
   334  }
   335  
   336  func Shutdown(s, how int) (err error) {
   337  	_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
   338  	if e != 0 {
   339  		err = e
   340  	}
   341  	return
   342  }
   343  
   344  func Fstatfs(fd int, buf *Statfs_t) (err error) {
   345  	_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
   346  	if e != 0 {
   347  		err = e
   348  	}
   349  	return
   350  }
   351  
   352  func Statfs(path string, buf *Statfs_t) (err error) {
   353  	pathp, err := BytePtrFromString(path)
   354  	if err != nil {
   355  		return err
   356  	}
   357  	_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
   358  	if e != 0 {
   359  		err = e
   360  	}
   361  	return
   362  }
   363  
   364  func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
   365  
   366  func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
   367  
   368  func (iov *Iovec) SetLen(length int) {
   369  	iov.Len = uint32(length)
   370  }
   371  
   372  func (msghdr *Msghdr) SetControllen(length int) {
   373  	msghdr.Controllen = uint32(length)
   374  }
   375  
   376  func (cmsg *Cmsghdr) SetLen(length int) {
   377  	cmsg.Len = uint32(length)
   378  }