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

View as plain text