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