...
Run Format

Source file src/syscall/syscall_linux_386.go

Documentation: syscall

     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  //sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
    55  //sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
    56  //sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
    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  //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
    86  
    87  func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
    88  	page := uintptr(offset / 4096)
    89  	if offset != int64(page)*4096 {
    90  		return 0, EINVAL
    91  	}
    92  	return mmap2(addr, length, prot, flags, fd, page)
    93  }
    94  
    95  type rlimit32 struct {
    96  	Cur uint32
    97  	Max uint32
    98  }
    99  
   100  //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
   101  
   102  const rlimInf32 = ^uint32(0)
   103  const rlimInf64 = ^uint64(0)
   104  
   105  func Getrlimit(resource int, rlim *Rlimit) (err error) {
   106  	err = prlimit(0, resource, nil, rlim)
   107  	if err != ENOSYS {
   108  		return err
   109  	}
   110  
   111  	rl := rlimit32{}
   112  	err = getrlimit(resource, &rl)
   113  	if err != nil {
   114  		return
   115  	}
   116  
   117  	if rl.Cur == rlimInf32 {
   118  		rlim.Cur = rlimInf64
   119  	} else {
   120  		rlim.Cur = uint64(rl.Cur)
   121  	}
   122  
   123  	if rl.Max == rlimInf32 {
   124  		rlim.Max = rlimInf64
   125  	} else {
   126  		rlim.Max = uint64(rl.Max)
   127  	}
   128  	return
   129  }
   130  
   131  //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
   132  
   133  func Setrlimit(resource int, rlim *Rlimit) (err error) {
   134  	err = prlimit(0, resource, rlim, nil)
   135  	if err != ENOSYS {
   136  		return err
   137  	}
   138  
   139  	rl := rlimit32{}
   140  	if rlim.Cur == rlimInf64 {
   141  		rl.Cur = rlimInf32
   142  	} else if rlim.Cur < uint64(rlimInf32) {
   143  		rl.Cur = uint32(rlim.Cur)
   144  	} else {
   145  		return EINVAL
   146  	}
   147  	if rlim.Max == rlimInf64 {
   148  		rl.Max = rlimInf32
   149  	} else if rlim.Max < uint64(rlimInf32) {
   150  		rl.Max = uint32(rlim.Max)
   151  	} else {
   152  		return EINVAL
   153  	}
   154  
   155  	return setrlimit(resource, &rl)
   156  }
   157  
   158  // Underlying system call writes to newoffset via pointer.
   159  // Implemented in assembly to avoid allocation.
   160  func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
   161  
   162  func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
   163  	newoffset, errno := seek(fd, offset, whence)
   164  	if errno != 0 {
   165  		return 0, errno
   166  	}
   167  	return newoffset, nil
   168  }
   169  
   170  // Vsyscalls on amd64.
   171  //sysnb	Gettimeofday(tv *Timeval) (err error)
   172  //sysnb	Time(t *Time_t) (tt Time_t, err error)
   173  
   174  // On x86 Linux, all the socket calls go through an extra indirection,
   175  // I think because the 5-register system call interface can't handle
   176  // the 6-argument calls like sendto and recvfrom. Instead the
   177  // arguments to the underlying system call are the number below
   178  // and a pointer to an array of uintptr. We hide the pointer in the
   179  // socketcall assembly to avoid allocation on every system call.
   180  
   181  const (
   182  	// see linux/net.h
   183  	_SOCKET      = 1
   184  	_BIND        = 2
   185  	_CONNECT     = 3
   186  	_LISTEN      = 4
   187  	_ACCEPT      = 5
   188  	_GETSOCKNAME = 6
   189  	_GETPEERNAME = 7
   190  	_SOCKETPAIR  = 8
   191  	_SEND        = 9
   192  	_RECV        = 10
   193  	_SENDTO      = 11
   194  	_RECVFROM    = 12
   195  	_SHUTDOWN    = 13
   196  	_SETSOCKOPT  = 14
   197  	_GETSOCKOPT  = 15
   198  	_SENDMSG     = 16
   199  	_RECVMSG     = 17
   200  	_ACCEPT4     = 18
   201  	_RECVMMSG    = 19
   202  	_SENDMMSG    = 20
   203  )
   204  
   205  func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
   206  func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
   207  
   208  func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
   209  	fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   210  	if e != 0 {
   211  		err = e
   212  	}
   213  	return
   214  }
   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  }
   379  
   380  func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
   381  	panic("not implemented")
   382  }
   383  

View as plain text