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