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