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