Home | History | Annotate | Download | only in unix
      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 // +build 386,linux
      9 
     10 package unix
     11 
     12 import (
     13 	"unsafe"
     14 )
     15 
     16 func setTimespec(sec, nsec int64) Timespec {
     17 	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
     18 }
     19 
     20 func setTimeval(sec, usec int64) Timeval {
     21 	return Timeval{Sec: int32(sec), Usec: int32(usec)}
     22 }
     23 
     24 //sysnb	pipe(p *[2]_C_int) (err error)
     25 
     26 func Pipe(p []int) (err error) {
     27 	if len(p) != 2 {
     28 		return EINVAL
     29 	}
     30 	var pp [2]_C_int
     31 	err = pipe(&pp)
     32 	p[0] = int(pp[0])
     33 	p[1] = int(pp[1])
     34 	return
     35 }
     36 
     37 //sysnb pipe2(p *[2]_C_int, flags int) (err error)
     38 
     39 func Pipe2(p []int, flags int) (err error) {
     40 	if len(p) != 2 {
     41 		return EINVAL
     42 	}
     43 	var pp [2]_C_int
     44 	err = pipe2(&pp, flags)
     45 	p[0] = int(pp[0])
     46 	p[1] = int(pp[1])
     47 	return
     48 }
     49 
     50 // 64-bit file system and 32-bit uid calls
     51 // (386 default is 32-bit file system and 16-bit uid).
     52 //sys	Dup2(oldfd int, newfd int) (err error)
     53 //sysnb	EpollCreate(size int) (fd int, err error)
     54 //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
     55 //sys	Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
     56 //sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
     57 //sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
     58 //sys	Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
     59 //sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
     60 //sysnb	Getegid() (egid int) = SYS_GETEGID32
     61 //sysnb	Geteuid() (euid int) = SYS_GETEUID32
     62 //sysnb	Getgid() (gid int) = SYS_GETGID32
     63 //sysnb	Getuid() (uid int) = SYS_GETUID32
     64 //sysnb	InotifyInit() (fd int, err error)
     65 //sys	Ioperm(from int, num int, on int) (err error)
     66 //sys	Iopl(level int) (err error)
     67 //sys	Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
     68 //sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
     69 //sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
     70 //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
     71 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
     72 //sys	Setfsgid(gid int) (err error) = SYS_SETFSGID32
     73 //sys	Setfsuid(uid int) (err error) = SYS_SETFSUID32
     74 //sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
     75 //sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
     76 //sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
     77 //sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
     78 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
     79 //sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
     80 //sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
     81 //sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
     82 //sys	Ustat(dev int, ubuf *Ustat_t) (err error)
     83 //sysnb	getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
     84 //sysnb	setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
     85 //sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
     86 
     87 //sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
     88 //sys	Pause() (err error)
     89 
     90 func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
     91 	page := uintptr(offset / 4096)
     92 	if offset != int64(page)*4096 {
     93 		return 0, EINVAL
     94 	}
     95 	return mmap2(addr, length, prot, flags, fd, page)
     96 }
     97 
     98 type rlimit32 struct {
     99 	Cur uint32
    100 	Max uint32
    101 }
    102 
    103 //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
    104 
    105 const rlimInf32 = ^uint32(0)
    106 const rlimInf64 = ^uint64(0)
    107 
    108 func Getrlimit(resource int, rlim *Rlimit) (err error) {
    109 	err = prlimit(0, resource, nil, rlim)
    110 	if err != ENOSYS {
    111 		return err
    112 	}
    113 
    114 	rl := rlimit32{}
    115 	err = getrlimit(resource, &rl)
    116 	if err != nil {
    117 		return
    118 	}
    119 
    120 	if rl.Cur == rlimInf32 {
    121 		rlim.Cur = rlimInf64
    122 	} else {
    123 		rlim.Cur = uint64(rl.Cur)
    124 	}
    125 
    126 	if rl.Max == rlimInf32 {
    127 		rlim.Max = rlimInf64
    128 	} else {
    129 		rlim.Max = uint64(rl.Max)
    130 	}
    131 	return
    132 }
    133 
    134 //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
    135 
    136 func Setrlimit(resource int, rlim *Rlimit) (err error) {
    137 	err = prlimit(0, resource, rlim, nil)
    138 	if err != ENOSYS {
    139 		return err
    140 	}
    141 
    142 	rl := rlimit32{}
    143 	if rlim.Cur == rlimInf64 {
    144 		rl.Cur = rlimInf32
    145 	} else if rlim.Cur < uint64(rlimInf32) {
    146 		rl.Cur = uint32(rlim.Cur)
    147 	} else {
    148 		return EINVAL
    149 	}
    150 	if rlim.Max == rlimInf64 {
    151 		rl.Max = rlimInf32
    152 	} else if rlim.Max < uint64(rlimInf32) {
    153 		rl.Max = uint32(rlim.Max)
    154 	} else {
    155 		return EINVAL
    156 	}
    157 
    158 	return setrlimit(resource, &rl)
    159 }
    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 //sys	futimesat(dirfd int, path string, times *[2]Timeval) (err error)
    170 //sysnb	Gettimeofday(tv *Timeval) (err error)
    171 //sysnb	Time(t *Time_t) (tt Time_t, err error)
    172 //sys	Utime(path string, buf *Utimbuf) (err error)
    173 //sys	utimes(path string, times *[2]Timeval) (err error)
    174 
    175 // On x86 Linux, all the socket calls go through an extra indirection,
    176 // I think because the 5-register system call interface can't handle
    177 // the 6-argument calls like sendto and recvfrom. Instead the
    178 // arguments to the underlying system call are the number below
    179 // and a pointer to an array of uintptr. We hide the pointer in the
    180 // socketcall assembly to avoid allocation on every system call.
    181 
    182 const (
    183 	// see linux/net.h
    184 	_SOCKET      = 1
    185 	_BIND        = 2
    186 	_CONNECT     = 3
    187 	_LISTEN      = 4
    188 	_ACCEPT      = 5
    189 	_GETSOCKNAME = 6
    190 	_GETPEERNAME = 7
    191 	_SOCKETPAIR  = 8
    192 	_SEND        = 9
    193 	_RECV        = 10
    194 	_SENDTO      = 11
    195 	_RECVFROM    = 12
    196 	_SHUTDOWN    = 13
    197 	_SETSOCKOPT  = 14
    198 	_GETSOCKOPT  = 15
    199 	_SENDMSG     = 16
    200 	_RECVMSG     = 17
    201 	_ACCEPT4     = 18
    202 	_RECVMMSG    = 19
    203 	_SENDMMSG    = 20
    204 )
    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 //sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
    379 
    380 func Poll(fds []PollFd, timeout int) (n int, err error) {
    381 	if len(fds) == 0 {
    382 		return poll(nil, 0, timeout)
    383 	}
    384 	return poll(&fds[0], len(fds), timeout)
    385 }
    386