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