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