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