source: code/trunk/vendor/modernc.org/libc/libc_linux_amd64.go@ 822

Last change on this file since 822 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.7 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 if cmd == fcntl.F_SETFL {
73 arg |= unix.O_LARGEFILE
74 }
75 n, _, err := unix.Syscall(unix.SYS_FCNTL, 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.Syscall(unix.SYS_LSTAT, pathname, statbuf, 0); err != 0 {
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_STAT, 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_FSTAT, 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
138func Xmmap(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
139 return Xmmap64(t, addr, length, prot, flags, fd, offset)
140}
141
142// void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
143func Xmmap64(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr {
144 data, _, err := unix.Syscall6(unix.SYS_MMAP, addr, uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
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 *mremap(void *old_address, size_t old_size, size_t new_size, int flags, ... /* void *new_address */);
160func Xmremap(t *TLS, old_address uintptr, old_size, new_size types.Size_t, flags int32, args uintptr) uintptr {
161 var arg uintptr
162 if args != 0 {
163 arg = *(*uintptr)(unsafe.Pointer(args))
164 }
165 data, _, err := unix.Syscall6(unix.SYS_MREMAP, old_address, uintptr(old_size), uintptr(new_size), uintptr(flags), arg, 0)
166 if err != 0 {
167 // if dmesgs {
168 // dmesg("%v: %v", origin(1), err)
169 // }
170 t.setErrno(err)
171 return ^uintptr(0) // (void*)-1
172 }
173
174 // if dmesgs {
175 // dmesg("%v: %#x", origin(1), data)
176 // }
177 return data
178}
179
180// int ftruncate(int fd, off_t length);
181func Xftruncate64(t *TLS, fd int32, length types.Off_t) int32 {
182 if _, _, err := unix.Syscall(unix.SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0); err != 0 {
183 // if dmesgs {
184 // dmesg("%v: fd %d: %v", origin(1), fd, err)
185 // }
186 t.setErrno(err)
187 return -1
188 }
189
190 // if dmesgs {
191 // dmesg("%v: %d %#x: ok", origin(1), fd, length)
192 // }
193 return 0
194}
195
196// off64_t lseek64(int fd, off64_t offset, int whence);
197func Xlseek64(t *TLS, fd int32, offset types.Off_t, whence int32) types.Off_t {
198 n, _, err := unix.Syscall(unix.SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
199 if err != 0 {
200 // if dmesgs {
201 // dmesg("%v: fd %v, off %#x, whence %v: %v", origin(1), fd, offset, whenceStr(whence), err)
202 // }
203 t.setErrno(err)
204 return -1
205 }
206
207 // if dmesgs {
208 // dmesg("%v: fd %v, off %#x, whence %v: %#x", origin(1), fd, offset, whenceStr(whence), n)
209 // }
210 return types.Off_t(n)
211}
212
213// int utime(const char *filename, const struct utimbuf *times);
214func Xutime(t *TLS, filename, times uintptr) int32 {
215 if _, _, err := unix.Syscall(unix.SYS_UTIME, filename, times, 0); err != 0 {
216 t.setErrno(err)
217 return -1
218 }
219
220 return 0
221}
222
223// unsigned int alarm(unsigned int seconds);
224func Xalarm(t *TLS, seconds uint32) uint32 {
225 n, _, err := unix.Syscall(unix.SYS_ALARM, uintptr(seconds), 0, 0)
226 if err != 0 {
227 panic(todo(""))
228 }
229
230 return uint32(n)
231}
232
233// time_t time(time_t *tloc);
234func Xtime(t *TLS, tloc uintptr) types.Time_t {
235 n, _, err := unix.Syscall(unix.SYS_TIME, tloc, 0, 0)
236 if err != 0 {
237 t.setErrno(err)
238 return types.Time_t(-1)
239 }
240
241 if tloc != 0 {
242 *(*types.Time_t)(unsafe.Pointer(tloc)) = types.Time_t(n)
243 }
244 return types.Time_t(n)
245}
246
247// int getrlimit(int resource, struct rlimit *rlim);
248func Xgetrlimit64(t *TLS, resource int32, rlim uintptr) int32 {
249 if _, _, err := unix.Syscall(unix.SYS_GETRLIMIT, uintptr(resource), uintptr(rlim), 0); err != 0 {
250 t.setErrno(err)
251 return -1
252 }
253
254 return 0
255}
256
257// int mkdir(const char *path, mode_t mode);
258func Xmkdir(t *TLS, path uintptr, mode types.Mode_t) int32 {
259 if _, _, err := unix.Syscall(unix.SYS_MKDIR, path, uintptr(mode), 0); err != 0 {
260 t.setErrno(err)
261 return -1
262 }
263
264 // if dmesgs {
265 // dmesg("%v: %q: ok", origin(1), GoString(path))
266 // }
267 return 0
268}
269
270// int symlink(const char *target, const char *linkpath);
271func Xsymlink(t *TLS, target, linkpath uintptr) int32 {
272 if _, _, err := unix.Syscall(unix.SYS_SYMLINK, target, linkpath, 0); err != 0 {
273 t.setErrno(err)
274 return -1
275 }
276
277 // if dmesgs {
278 // dmesg("%v: %q %q: ok", origin(1), GoString(target), GoString(linkpath))
279 // }
280 return 0
281}
282
283// int chmod(const char *pathname, mode_t mode)
284func Xchmod(t *TLS, pathname uintptr, mode types.Mode_t) int32 {
285 if _, _, err := unix.Syscall(unix.SYS_CHMOD, pathname, uintptr(mode), 0); err != 0 {
286 t.setErrno(err)
287 return -1
288 }
289
290 // if dmesgs {
291 // dmesg("%v: %q %#o: ok", origin(1), GoString(pathname), mode)
292 // }
293 return 0
294}
295
296// int utimes(const char *filename, const struct timeval times[2]);
297func Xutimes(t *TLS, filename, times uintptr) int32 {
298 if _, _, err := unix.Syscall(unix.SYS_UTIMES, filename, times, 0); err != 0 {
299 t.setErrno(err)
300 return -1
301 }
302
303 // if dmesgs {
304 // dmesg("%v: %q: ok", origin(1), GoString(filename))
305 // }
306 return 0
307}
308
309// int unlink(const char *pathname);
310func Xunlink(t *TLS, pathname uintptr) int32 {
311 if _, _, err := unix.Syscall(unix.SYS_UNLINK, pathname, 0, 0); err != 0 {
312 t.setErrno(err)
313 return -1
314 }
315
316 // if dmesgs {
317 // dmesg("%v: %q: ok", origin(1), GoString(pathname))
318 // }
319 return 0
320}
321
322// int access(const char *pathname, int mode);
323func Xaccess(t *TLS, pathname uintptr, mode int32) int32 {
324 if _, _, err := unix.Syscall(unix.SYS_ACCESS, pathname, uintptr(mode), 0); err != 0 {
325 // if dmesgs {
326 // dmesg("%v: %q: %v", origin(1), GoString(pathname), err)
327 // }
328 t.setErrno(err)
329 return -1
330 }
331
332 // if dmesgs {
333 // dmesg("%v: %q %#o: ok", origin(1), GoString(pathname), mode)
334 // }
335 return 0
336}
337
338// int rmdir(const char *pathname);
339func Xrmdir(t *TLS, pathname uintptr) int32 {
340 if _, _, err := unix.Syscall(unix.SYS_RMDIR, pathname, 0, 0); err != 0 {
341 t.setErrno(err)
342 return -1
343 }
344
345 // if dmesgs {
346 // dmesg("%v: %q: ok", origin(1), GoString(pathname))
347 // }
348 return 0
349}
350
351// int rename(const char *oldpath, const char *newpath);
352func Xrename(t *TLS, oldpath, newpath uintptr) int32 {
353 if _, _, err := unix.Syscall(unix.SYS_RENAME, oldpath, newpath, 0); err != 0 {
354 t.setErrno(err)
355 return -1
356 }
357
358 return 0
359}
360
361// int mknod(const char *pathname, mode_t mode, dev_t dev);
362func Xmknod(t *TLS, pathname uintptr, mode types.Mode_t, dev types.Dev_t) int32 {
363 if _, _, err := unix.Syscall(unix.SYS_MKNOD, pathname, uintptr(mode), uintptr(dev)); err != 0 {
364 t.setErrno(err)
365 return -1
366 }
367
368 return 0
369}
370
371// int chown(const char *pathname, uid_t owner, gid_t group);
372func Xchown(t *TLS, pathname uintptr, owner types.Uid_t, group types.Gid_t) int32 {
373 if _, _, err := unix.Syscall(unix.SYS_CHOWN, pathname, uintptr(owner), uintptr(group)); err != 0 {
374 t.setErrno(err)
375 return -1
376 }
377
378 return 0
379}
380
381// int link(const char *oldpath, const char *newpath);
382func Xlink(t *TLS, oldpath, newpath uintptr) int32 {
383 if _, _, err := unix.Syscall(unix.SYS_LINK, oldpath, newpath, 0); err != 0 {
384 t.setErrno(err)
385 return -1
386 }
387
388 return 0
389}
390
391// int pipe(int pipefd[2]);
392func Xpipe(t *TLS, pipefd uintptr) int32 {
393 if _, _, err := unix.Syscall(unix.SYS_PIPE, pipefd, 0, 0); err != 0 {
394 t.setErrno(err)
395 return -1
396 }
397
398 return 0
399}
400
401// int dup2(int oldfd, int newfd);
402func Xdup2(t *TLS, oldfd, newfd int32) int32 {
403 n, _, err := unix.Syscall(unix.SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
404 if err != 0 {
405 t.setErrno(err)
406 return -1
407 }
408
409 return int32(n)
410}
411
412// ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);
413func Xreadlink(t *TLS, path, buf uintptr, bufsize types.Size_t) types.Ssize_t {
414 n, _, err := unix.Syscall(unix.SYS_READLINK, path, buf, uintptr(bufsize))
415 if err != 0 {
416 t.setErrno(err)
417 return -1
418 }
419
420 return types.Ssize_t(n)
421}
422
423// FILE *fopen64(const char *pathname, const char *mode);
424func Xfopen64(t *TLS, pathname, mode uintptr) uintptr {
425 m := strings.ReplaceAll(GoString(mode), "b", "")
426 var flags int
427 switch m {
428 case "r":
429 flags = os.O_RDONLY
430 case "r+":
431 flags = os.O_RDWR
432 case "w":
433 flags = os.O_WRONLY | os.O_CREATE | os.O_TRUNC
434 case "w+":
435 flags = os.O_RDWR | os.O_CREATE | os.O_TRUNC
436 case "a":
437 flags = os.O_WRONLY | os.O_CREATE | os.O_APPEND
438 case "a+":
439 flags = os.O_RDWR | os.O_CREATE | os.O_APPEND
440 default:
441 panic(m)
442 }
443 //TODO- flags |= fcntl.O_LARGEFILE
444 fd, _, err := unix.Syscall(unix.SYS_OPEN, pathname, uintptr(flags|unix.O_LARGEFILE), 0666)
445 if err != 0 {
446 t.setErrno(err)
447 return 0
448 }
449
450 if p := newFile(t, int32(fd)); p != 0 {
451 return p
452 }
453
454 Xclose(t, int32(fd))
455 t.setErrno(errno.ENOMEM)
456 return 0
457}
458
459// int iswspace(wint_t wc);
460func Xiswspace(t *TLS, wc wctype.Wint_t) int32 {
461 return Bool32(unicode.IsSpace(rune(wc)))
462}
463
464// int iswalnum(wint_t wc);
465func Xiswalnum(t *TLS, wc wctype.Wint_t) int32 {
466 return Bool32(unicode.IsLetter(rune(wc)) || unicode.IsNumber(rune(wc)))
467}
Note: See TracBrowser for help on using the repository browser.