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