source: code/trunk/vendor/modernc.org/libc/libc_linux_arm.go@ 823

Last change on this file since 823 was 822, checked in by yakumo.izuru, 22 months ago

Prefer immortal.run over runit and rc.d, use vendored modules
for convenience.

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 11.3 KB
Line 
1// Copyright 2020 The Libc 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
5package libc // import "modernc.org/libc"
6
7import (
8 "os"
9 "strings"
10 "time"
11 "unsafe"
12
13 "golang.org/x/sys/unix"
14 "modernc.org/libc/errno"
15 "modernc.org/libc/fcntl"
16 "modernc.org/libc/signal"
17 "modernc.org/libc/sys/stat"
18 "modernc.org/libc/sys/types"
19)
20
21// int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
22func Xsigaction(t *TLS, signum int32, act, oldact uintptr) int32 {
23 // musl/arch/x32/ksigaction.h
24 //
25 // struct k_sigaction {
26 // void (*handler)(int);
27 // unsigned long flags;
28 // void (*restorer)(void);
29 // unsigned mask[2];
30 // };
31 type k_sigaction struct {
32 handler uintptr
33 flags ulong
34 restorer uintptr
35 mask [2]uint32
36 }
37
38 var kact, koldact uintptr
39 if act != 0 {
40 sz := int(unsafe.Sizeof(k_sigaction{}))
41 kact = t.Alloc(sz)
42 defer t.Free(sz)
43 *(*k_sigaction)(unsafe.Pointer(kact)) = k_sigaction{
44 handler: (*signal.Sigaction)(unsafe.Pointer(act)).F__sigaction_handler.Fsa_handler,
45 flags: ulong((*signal.Sigaction)(unsafe.Pointer(act)).Fsa_flags),
46 restorer: (*signal.Sigaction)(unsafe.Pointer(act)).Fsa_restorer,
47 }
48 Xmemcpy(t, kact+unsafe.Offsetof(k_sigaction{}.mask), act+unsafe.Offsetof(signal.Sigaction{}.Fsa_mask), types.Size_t(unsafe.Sizeof(k_sigaction{}.mask)))
49 }
50 if oldact != 0 {
51 panic(todo(""))
52 }
53
54 if _, _, err := unix.Syscall6(unix.SYS_RT_SIGACTION, uintptr(signum), kact, koldact, unsafe.Sizeof(k_sigaction{}.mask), 0, 0); err != 0 {
55 t.setErrno(err)
56 return -1
57 }
58
59 if oldact != 0 {
60 panic(todo(""))
61 }
62
63 return 0
64}
65
66// int fcntl(int fd, int cmd, ... /* arg */ );
67func Xfcntl64(t *TLS, fd, cmd int32, args uintptr) int32 {
68 var arg uintptr
69 if args != 0 {
70 arg = *(*uintptr)(unsafe.Pointer(args))
71 }
72 if cmd == fcntl.F_SETFL {
73 arg |= unix.O_LARGEFILE
74 }
75 n, _, err := unix.Syscall(unix.SYS_FCNTL64, uintptr(fd), uintptr(cmd), arg)
76 if err != 0 {
77 if dmesgs {
78 dmesg("%v: fd %v cmd %v", origin(1), fcntlCmdStr(fd), cmd)
79 }
80 t.setErrno(err)
81 return -1
82 }
83
84 if dmesgs {
85 dmesg("%v: %d %s %#x: %d", origin(1), fd, fcntlCmdStr(cmd), arg, n)
86 }
87 return int32(n)
88}
89
90// int lstat(const char *pathname, struct stat *statbuf);
91func Xlstat64(t *TLS, pathname, statbuf uintptr) int32 {
92 if err := unix.Lstat(GoString(pathname), (*unix.Stat_t)(unsafe.Pointer(statbuf))); err != nil {
93 if dmesgs {
94 dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
95 }
96 t.setErrno(err)
97 return -1
98 }
99
100 if dmesgs {
101 dmesg("%v: %q: ok", origin(1), GoString(pathname))
102 }
103 return 0
104}
105
106// int stat(const char *pathname, struct stat *statbuf);
107func Xstat64(t *TLS, pathname, statbuf uintptr) int32 {
108 if _, _, err := unix.Syscall(unix.SYS_STAT64, pathname, statbuf, 0); err != 0 {
109 if dmesgs {
110 dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
111 }
112 t.setErrno(err)
113 return -1
114 }
115
116 if dmesgs {
117 dmesg("%v: %q: ok", origin(1), GoString(pathname))
118 }
119 return 0
120}
121
122// int fstat(int fd, struct stat *statbuf);
123func Xfstat64(t *TLS, fd int32, statbuf uintptr) int32 {
124 if _, _, err := unix.Syscall(unix.SYS_FSTAT64, uintptr(fd), statbuf, 0); err != 0 {
125 if dmesgs {
126 dmesg("%v: fd %d: %v", origin(1), fd, err)
127 }
128 t.setErrno(err)
129 return -1
130 }
131
132 if dmesgs {
133 dmesg("%v: %d, size %#x: ok\n%+v", origin(1), fd, (*stat.Stat)(unsafe.Pointer(statbuf)).Fst_size, (*stat.Stat)(unsafe.Pointer(statbuf)))
134 }
135 return 0
136}
137
138// void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, ... /* void *new_address */);
139func Xmremap(t *TLS, old_address uintptr, old_size, new_size types.Size_t, flags int32, args uintptr) uintptr {
140 var arg uintptr
141 if args != 0 {
142 arg = *(*uintptr)(unsafe.Pointer(args))
143 }
144 data, _, err := unix.Syscall6(unix.SYS_MREMAP, old_address, uintptr(old_size), uintptr(new_size), uintptr(flags), arg, 0)
145 if err != 0 {
146 if dmesgs {
147 dmesg("%v: %v", origin(1), err)
148 }
149 t.setErrno(err)
150 return ^uintptr(0) // (void*)-1
151 }
152
153 if dmesgs {
154 dmesg("%v: %#x", origin(1), data)
155 }
156 return data
157}
158
159// void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
160func Xmmap(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
161 return Xmmap64(t, addr, length, prot, flags, fd, offset)
162}
163
164// void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
165func Xmmap64(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
166 data, _, err := unix.Syscall6(unix.SYS_MMAP2, addr, uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset>>12))
167 if err != 0 {
168 if dmesgs {
169 dmesg("%v: %v", origin(1), err)
170 }
171 t.setErrno(err)
172 return ^uintptr(0) // (void*)-1
173 }
174
175 if dmesgs {
176 dmesg("%v: %#x", origin(1), data)
177 }
178 return data
179}
180
181// int symlink(const char *target, const char *linkpath);
182func Xsymlink(t *TLS, target, linkpath uintptr) int32 {
183 if err := unix.Symlink(GoString(target), GoString(linkpath)); err != nil {
184 t.setErrno(err)
185 return -1
186 }
187
188 if dmesgs {
189 dmesg("%v: %q %q: ok", origin(1), GoString(target), GoString(linkpath))
190 }
191 return 0
192}
193
194// int chmod(const char *pathname, mode_t mode)
195func Xchmod(t *TLS, pathname uintptr, mode types.Mode_t) int32 {
196 if err := unix.Chmod(GoString(pathname), uint32(mode)); err != nil {
197 t.setErrno(err)
198 return -1
199 }
200
201 if dmesgs {
202 dmesg("%v: %q %#o: ok", origin(1), GoString(pathname), mode)
203 }
204 return 0
205}
206
207// int ftruncate(int fd, off_t length);
208func Xftruncate64(t *TLS, fd int32, length types.Off_t) int32 {
209 if _, _, err := unix.Syscall6(unix.SYS_FTRUNCATE64, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0); err != 0 {
210 if dmesgs {
211 dmesg("%v: fd %d: %v", origin(1), fd, err)
212 }
213 t.setErrno(err)
214 return -1
215 }
216
217 if dmesgs {
218 dmesg("%v: %d %#x: ok", origin(1), fd, length)
219 }
220 return 0
221}
222
223// off64_t lseek64(int fd, off64_t offset, int whence);
224func Xlseek64(t *TLS, fd int32, offset types.Off_t, whence int32) types.Off_t {
225 n, err := unix.Seek(int(fd), int64(offset), int(whence))
226 if err != nil {
227 if dmesgs {
228 dmesg("%v: fd %v, off %#x, whence %v: %v", origin(1), fd, offset, whenceStr(whence), err)
229 }
230 t.setErrno(err)
231 return -1
232 }
233
234 if dmesgs {
235 dmesg("%v: fd %v, off %#x, whence %v: %#x", origin(1), fd, offset, whenceStr(whence), n)
236 }
237 return types.Off_t(n)
238}
239
240// int utime(const char *filename, const struct utimbuf *times);
241func Xutime(t *TLS, filename, times uintptr) int32 {
242 if err := unix.Utime(GoString(filename), (*unix.Utimbuf)(unsafe.Pointer(times))); err != nil {
243 t.setErrno(err)
244 return -1
245 }
246
247 return 0
248}
249
250// unsigned int alarm(unsigned int seconds);
251func Xalarm(t *TLS, seconds uint32) uint32 {
252 panic(todo(""))
253}
254
255// int getrlimit(int resource, struct rlimit *rlim);
256func Xgetrlimit64(t *TLS, resource int32, rlim uintptr) int32 {
257 if err := unix.Getrlimit(int(resource), (*unix.Rlimit)(unsafe.Pointer(rlim))); err != nil {
258 t.setErrno(err)
259 return -1
260 }
261
262 return 0
263}
264
265// time_t time(time_t *tloc);
266func Xtime(t *TLS, tloc uintptr) types.Time_t {
267 n := time.Now().UTC().Unix()
268 if tloc != 0 {
269 *(*types.Time_t)(unsafe.Pointer(tloc)) = types.Time_t(n)
270 }
271 return types.Time_t(n)
272}
273
274// int utimes(const char *filename, const struct timeval times[2]);
275func Xutimes(t *TLS, filename, times uintptr) int32 {
276 var tv []unix.Timeval
277 if times != 0 {
278 tv = make([]unix.Timeval, 2)
279 *(*[2]unix.Timeval)(unsafe.Pointer(&tv[0])) = *(*[2]unix.Timeval)(unsafe.Pointer(times))
280 }
281 if err := unix.Utimes(GoString(filename), tv); err != nil {
282 t.setErrno(err)
283 return -1
284 }
285
286 if times != 0 {
287 *(*[2]unix.Timeval)(unsafe.Pointer(times)) = *(*[2]unix.Timeval)(unsafe.Pointer(&tv[0]))
288 }
289 if dmesgs {
290 dmesg("%v: %q: ok", origin(1), GoString(filename))
291 }
292 return 0
293}
294
295// int unlink(const char *pathname);
296func Xunlink(t *TLS, pathname uintptr) int32 {
297 if err := unix.Unlinkat(unix.AT_FDCWD, GoString(pathname), 0); err != nil {
298 t.setErrno(err)
299 return -1
300 }
301
302 if dmesgs {
303 dmesg("%v: %q: ok", origin(1), GoString(pathname))
304 }
305 return 0
306}
307
308// int access(const char *pathname, int mode);
309func Xaccess(t *TLS, pathname uintptr, mode int32) int32 {
310 if err := unix.Faccessat(unix.AT_FDCWD, GoString(pathname), uint32(mode), 0); err != nil {
311 if dmesgs {
312 dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
313 }
314 t.setErrno(err)
315 return -1
316 }
317
318 if dmesgs {
319 dmesg("%v: %q %#o: ok", origin(1), GoString(pathname), mode)
320 }
321 return 0
322}
323
324// int rmdir(const char *pathname);
325func Xrmdir(t *TLS, pathname uintptr) int32 {
326 if err := unix.Rmdir(GoString(pathname)); err != nil {
327 t.setErrno(err)
328 return -1
329 }
330
331 if dmesgs {
332 dmesg("%v: %q: ok", origin(1), GoString(pathname))
333 }
334 return 0
335}
336
337// int rename(const char *oldpath, const char *newpath);
338func Xrename(t *TLS, oldpath, newpath uintptr) int32 {
339 if err := unix.Rename(GoString(oldpath), GoString(newpath)); err != nil {
340 t.setErrno(err)
341 return -1
342 }
343
344 return 0
345}
346
347// int mknod(const char *pathname, mode_t mode, dev_t dev);
348func Xmknod(t *TLS, pathname uintptr, mode types.Mode_t, dev types.Dev_t) int32 {
349 panic(todo(""))
350}
351
352// int chown(const char *pathname, uid_t owner, gid_t group);
353func Xchown(t *TLS, pathname uintptr, owner types.Uid_t, group types.Gid_t) int32 {
354 if err := unix.Chown(GoString(pathname), int(owner), int(group)); err != nil {
355 t.setErrno(err)
356 return -1
357 }
358
359 return 0
360}
361
362// int link(const char *oldpath, const char *newpath);
363func Xlink(t *TLS, oldpath, newpath uintptr) int32 {
364 panic(todo(""))
365}
366
367// int pipe(int pipefd[2]);
368func Xpipe(t *TLS, pipefd uintptr) int32 {
369 if _, _, err := unix.Syscall(unix.SYS_PIPE2, pipefd, 0, 0); err != 0 {
370 t.setErrno(err)
371 return -1
372 }
373
374 return 0
375}
376
377// int dup2(int oldfd, int newfd);
378func Xdup2(t *TLS, oldfd, newfd int32) int32 {
379 panic(todo(""))
380}
381
382// ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);
383func Xreadlink(t *TLS, path, buf uintptr, bufsize types.Size_t) types.Ssize_t {
384 n, err := unix.Readlink(GoString(path), GoBytes(buf, int(bufsize)))
385 if err != nil {
386 t.setErrno(err)
387 return -1
388 }
389
390 return types.Ssize_t(n)
391}
392
393// FILE *fopen64(const char *pathname, const char *mode);
394func Xfopen64(t *TLS, pathname, mode uintptr) uintptr {
395 m := strings.ReplaceAll(GoString(mode), "b", "")
396 var flags int
397 switch m {
398 case "r":
399 flags = os.O_RDONLY
400 case "r+":
401 flags = os.O_RDWR
402 case "w":
403 flags = os.O_WRONLY | os.O_CREATE | os.O_TRUNC
404 case "w+":
405 flags = os.O_RDWR | os.O_CREATE | os.O_TRUNC
406 case "a":
407 flags = os.O_WRONLY | os.O_CREATE | os.O_APPEND
408 case "a+":
409 flags = os.O_RDWR | os.O_CREATE | os.O_APPEND
410 default:
411 panic(m)
412 }
413 //TODO- flags |= fcntl.O_LARGEFILE
414 fd, _, err := unix.Syscall(unix.SYS_OPEN, pathname, uintptr(flags|unix.O_LARGEFILE), 0666)
415 if err != 0 {
416 t.setErrno(err)
417 return 0
418 }
419
420 if p := newFile(t, int32(fd)); p != 0 {
421 return p
422 }
423
424 Xclose(t, int32(fd))
425 t.setErrno(errno.ENOMEM)
426 return 0
427}
428
429// int mkdir(const char *path, mode_t mode);
430func Xmkdir(t *TLS, path uintptr, mode types.Mode_t) int32 {
431 if err := unix.Mkdir(GoString(path), uint32(mode)); err != nil {
432 t.setErrno(err)
433 return -1
434 }
435
436 if dmesgs {
437 dmesg("%v: %q: ok", origin(1), GoString(path))
438 }
439 return 0
440}
441
442//TODO- // int sscanf(const char *str, const char *format, ...);
443//TODO- func Xsscanf(t *TLS, str, format, va uintptr) int32 {
444//TODO- r := scanf(strings.NewReader(GoString(str)), format, va)
445//TODO- // if dmesgs {
446//TODO- // dmesg("%v: %q %q: %d", origin(1), GoString(str), GoString(format), r)
447//TODO- // }
448//TODO- return r
449//TODO- }
Note: See TracBrowser for help on using the repository browser.