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