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