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