Home | History | Annotate | Download | only in syscall
      1 // Copyright 2016 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 package syscall
      6 
      7 import "unsafe"
      8 
      9 const (
     10 	_SYS_dup       = SYS_DUP2
     11 	_SYS_setgroups = SYS_SETGROUPS
     12 )
     13 
     14 //sys	Dup2(oldfd int, newfd int) (err error)
     15 //sys	Fchown(fd int, uid int, gid int) (err error)
     16 //sys	Fstat(fd int, stat *Stat_t) (err error)
     17 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
     18 //sys	Ftruncate(fd int, length int64) (err error)
     19 //sysnb	Getegid() (egid int)
     20 //sysnb	Geteuid() (euid int)
     21 //sysnb	Getgid() (gid int)
     22 //sysnb	Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT
     23 //sysnb	Getuid() (uid int)
     24 //sysnb	InotifyInit() (fd int, err error)
     25 //sys	Lchown(path string, uid int, gid int) (err error)
     26 //sys	Lstat(path string, stat *Stat_t) (err error)
     27 //sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
     28 //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
     29 //sys	Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
     30 //sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
     31 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
     32 //sys	Setfsgid(gid int) (err error)
     33 //sys	Setfsuid(uid int) (err error)
     34 //sysnb	Setregid(rgid int, egid int) (err error)
     35 //sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
     36 //sysnb	Setresuid(ruid int, euid int, suid int) (err error)
     37 //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
     38 //sysnb	Setreuid(ruid int, euid int) (err error)
     39 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
     40 //sys	Stat(path string, stat *Stat_t) (err error)
     41 //sys	Statfs(path string, buf *Statfs_t) (err error)
     42 //sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE
     43 //sys	Truncate(path string, length int64) (err error)
     44 //sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
     45 //sysnb	setgroups(n int, list *_Gid_t) (err error)
     46 
     47 //sysnb	Gettimeofday(tv *Timeval) (err error)
     48 
     49 func Time(t *Time_t) (tt Time_t, err error) {
     50 	var tv Timeval
     51 	err = Gettimeofday(&tv)
     52 	if err != nil {
     53 		return 0, err
     54 	}
     55 	if t != nil {
     56 		*t = Time_t(tv.Sec)
     57 	}
     58 	return Time_t(tv.Sec), nil
     59 }
     60 
     61 func setTimespec(sec, nsec int64) Timespec {
     62 	return Timespec{Sec: sec, Nsec: nsec}
     63 }
     64 
     65 func setTimeval(sec, usec int64) Timeval {
     66 	return Timeval{Sec: sec, Usec: usec}
     67 }
     68 
     69 func Pipe(p []int) (err error) {
     70 	if len(p) != 2 {
     71 		return EINVAL
     72 	}
     73 	var pp [2]_C_int
     74 	err = pipe2(&pp, 0)
     75 	p[0] = int(pp[0])
     76 	p[1] = int(pp[1])
     77 	return
     78 }
     79 
     80 //sysnb pipe2(p *[2]_C_int, flags int) (err error)
     81 
     82 func Pipe2(p []int, flags int) (err error) {
     83 	if len(p) != 2 {
     84 		return EINVAL
     85 	}
     86 	var pp [2]_C_int
     87 	err = pipe2(&pp, flags)
     88 	p[0] = int(pp[0])
     89 	p[1] = int(pp[1])
     90 	return
     91 }
     92 
     93 // Linux on s390x uses the old mmap interface, which requires arguments to be passed in a struct.
     94 // mmap2 also requires arguments to be passed in a struct; it is currently not exposed in <asm/unistd.h>.
     95 func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
     96 	mmap_args := [6]uintptr{addr, length, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)}
     97 	r0, _, e1 := Syscall(SYS_MMAP, uintptr(unsafe.Pointer(&mmap_args[0])), 0, 0)
     98 	xaddr = uintptr(r0)
     99 	if e1 != 0 {
    100 		err = errnoErr(e1)
    101 	}
    102 	return
    103 }
    104 
    105 // On s390x Linux, all the socket calls go through an extra indirection.
    106 // The arguments to the underlying system call are the number below
    107 // and a pointer to an array of uintptr.  We hide the pointer in the
    108 // socketcall assembly to avoid allocation on every system call.
    109 
    110 const (
    111 	// see linux/net.h
    112 	_SOCKET      = 1
    113 	_BIND        = 2
    114 	_CONNECT     = 3
    115 	_LISTEN      = 4
    116 	_ACCEPT      = 5
    117 	_GETSOCKNAME = 6
    118 	_GETPEERNAME = 7
    119 	_SOCKETPAIR  = 8
    120 	_SEND        = 9
    121 	_RECV        = 10
    122 	_SENDTO      = 11
    123 	_RECVFROM    = 12
    124 	_SHUTDOWN    = 13
    125 	_SETSOCKOPT  = 14
    126 	_GETSOCKOPT  = 15
    127 	_SENDMSG     = 16
    128 	_RECVMSG     = 17
    129 	_ACCEPT4     = 18
    130 	_RECVMMSG    = 19
    131 	_SENDMMSG    = 20
    132 )
    133 
    134 func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
    135 func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
    136 
    137 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
    138 	fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
    139 	if e != 0 {
    140 		err = e
    141 	}
    142 	return
    143 }
    144 
    145 func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
    146 	fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
    147 	if e != 0 {
    148 		err = e
    149 	}
    150 	return
    151 }
    152 
    153 func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
    154 	_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
    155 	if e != 0 {
    156 		err = e
    157 	}
    158 	return
    159 }
    160 
    161 func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
    162 	_, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
    163 	if e != 0 {
    164 		err = e
    165 	}
    166 	return
    167 }
    168 
    169 func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
    170 	_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
    171 	if e != 0 {
    172 		err = e
    173 	}
    174 	return
    175 }
    176 
    177 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
    178 	_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
    179 	if e != 0 {
    180 		err = e
    181 	}
    182 	return
    183 }
    184 
    185 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
    186 	_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
    187 	if e != 0 {
    188 		err = e
    189 	}
    190 	return
    191 }
    192 
    193 func socket(domain int, typ int, proto int) (fd int, err error) {
    194 	fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
    195 	if e != 0 {
    196 		err = e
    197 	}
    198 	return
    199 }
    200 
    201 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
    202 	_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
    203 	if e != 0 {
    204 		err = e
    205 	}
    206 	return
    207 }
    208 
    209 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
    210 	_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
    211 	if e != 0 {
    212 		err = e
    213 	}
    214 	return
    215 }
    216 
    217 func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
    218 	var base uintptr
    219 	if len(p) > 0 {
    220 		base = uintptr(unsafe.Pointer(&p[0]))
    221 	}
    222 	n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
    223 	if e != 0 {
    224 		err = e
    225 	}
    226 	return
    227 }
    228 
    229 func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
    230 	var base uintptr
    231 	if len(p) > 0 {
    232 		base = uintptr(unsafe.Pointer(&p[0]))
    233 	}
    234 	_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))
    235 	if e != 0 {
    236 		err = e
    237 	}
    238 	return
    239 }
    240 
    241 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
    242 	n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
    243 	if e != 0 {
    244 		err = e
    245 	}
    246 	return
    247 }
    248 
    249 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
    250 	n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
    251 	if e != 0 {
    252 		err = e
    253 	}
    254 	return
    255 }
    256 
    257 func Listen(s int, n int) (err error) {
    258 	_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
    259 	if e != 0 {
    260 		err = e
    261 	}
    262 	return
    263 }
    264 
    265 func Shutdown(s, how int) (err error) {
    266 	_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
    267 	if e != 0 {
    268 		err = e
    269 	}
    270 	return
    271 }
    272 
    273 func (r *PtraceRegs) PC() uint64 { return r.Psw.Addr }
    274 
    275 func (r *PtraceRegs) SetPC(pc uint64) { r.Psw.Addr = pc }
    276 
    277 func (iov *Iovec) SetLen(length int) {
    278 	iov.Len = uint64(length)
    279 }
    280 
    281 func (msghdr *Msghdr) SetControllen(length int) {
    282 	msghdr.Controllen = uint64(length)
    283 }
    284 
    285 func (cmsg *Cmsghdr) SetLen(length int) {
    286 	cmsg.Len = uint64(length)
    287 }
    288 
    289 func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
    290 	panic("not implemented")
    291 }
    292