Home | History | Annotate | Download | only in 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