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