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