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