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