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