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