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