syscall_libc.mx raw
1 //go:build js || nintendoswitch || wasip1 || wasip2
2
3 package syscall
4
5 import (
6 "unsafe"
7 )
8
9 type sliceHeader struct {
10 buf *byte
11 len uintptr
12 cap uintptr
13 }
14
15 func Close(fd int) (err error) {
16 if libc_close(int32(fd)) < 0 {
17 err = getErrno()
18 }
19 return
20 }
21
22 func Dup(fd int) (fd2 int, err error) {
23 fd2 = int(libc_dup(int32(fd)))
24 if fd2 < 0 {
25 err = getErrno()
26 }
27 return
28 }
29
30 func Write(fd int, p []byte) (n int, err error) {
31 buf, count := splitSlice(p)
32 n = libc_write(int32(fd), buf, uint(count))
33 if n < 0 {
34 err = getErrno()
35 }
36 return
37 }
38
39 func Read(fd int, p []byte) (n int, err error) {
40 buf, count := splitSlice(p)
41 n = libc_read(int32(fd), buf, uint(count))
42 if n < 0 {
43 err = getErrno()
44 }
45 return
46 }
47
48 func Pread(fd int, p []byte, offset int64) (n int, err error) {
49 buf, count := splitSlice(p)
50 n = libc_pread(int32(fd), buf, uint(count), offset)
51 if n < 0 {
52 err = getErrno()
53 }
54 return
55 }
56
57 func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
58 buf, count := splitSlice(p)
59 n = libc_pwrite(int32(fd), buf, uint(count), offset)
60 if n < 0 {
61 err = getErrno()
62 }
63 return
64 }
65
66 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
67 newoffset = libc_lseek(int32(fd), offset, whence)
68 if newoffset < 0 {
69 err = getErrno()
70 }
71 return
72 }
73
74 func Open(path string, flag int, mode uint32) (fd int, err error) {
75 data := cstring(path)
76 fd = int(libc_open(&data[0], int32(flag), mode))
77 if fd < 0 {
78 err = getErrno()
79 }
80 return
81 }
82
83 func Fsync(fd int) (err error) {
84 if libc_fsync(int32(fd)) < 0 {
85 err = getErrno()
86 }
87 return
88 }
89
90 func Readlink(path string, p []byte) (n int, err error) {
91 data := cstring(path)
92 buf, count := splitSlice(p)
93 n = libc_readlink(&data[0], buf, uint(count))
94 if n < 0 {
95 err = getErrno()
96 }
97 return
98 }
99
100 func Chdir(path string) (err error) {
101 data := cstring(path)
102 fail := int(libc_chdir(&data[0]))
103 if fail < 0 {
104 err = getErrno()
105 }
106 return
107 }
108
109 func Mkdir(path string, mode uint32) (err error) {
110 data := cstring(path)
111 fail := int(libc_mkdir(&data[0], mode))
112 if fail < 0 {
113 err = getErrno()
114 }
115 return
116 }
117
118 func Rmdir(path string) (err error) {
119 data := cstring(path)
120 fail := int(libc_rmdir(&data[0]))
121 if fail < 0 {
122 err = getErrno()
123 }
124 return
125 }
126
127 func Rename(from, to string) (err error) {
128 fromdata := cstring(from)
129 todata := cstring(to)
130 fail := int(libc_rename(&fromdata[0], &todata[0]))
131 if fail < 0 {
132 err = getErrno()
133 }
134 return
135 }
136
137 func Link(oldname, newname string) (err error) {
138 fromdata := cstring(oldname)
139 todata := cstring(newname)
140 fail := int(libc_link(&fromdata[0], &todata[0]))
141 if fail < 0 {
142 err = getErrno()
143 }
144 return
145 }
146
147 func Symlink(from, to string) (err error) {
148 fromdata := cstring(from)
149 todata := cstring(to)
150 fail := int(libc_symlink(&fromdata[0], &todata[0]))
151 if fail < 0 {
152 err = getErrno()
153 }
154 return
155 }
156
157 func Unlink(path string) (err error) {
158 data := cstring(path)
159 fail := int(libc_unlink(&data[0]))
160 if fail < 0 {
161 err = getErrno()
162 }
163 return
164 }
165
166 func Chown(path string, uid, gid int) (err error) {
167 data := cstring(path)
168 fail := int(libc_chown(&data[0], uid, gid))
169 if fail < 0 {
170 err = getErrno()
171 }
172 return
173 }
174
175 func Fork() (err error) {
176 fail := int(libc_fork())
177 if fail < 0 {
178 err = getErrno()
179 }
180 return
181 }
182
183 func Execve(pathname string, argv []string, envv []string) (err error) {
184 argv0 := cstring(pathname)
185
186 // transform argv and envv into the format expected by execve
187 argv1 := make([]*byte, len(argv)+1)
188 for i, arg := range argv {
189 argv1[i] = &cstring(arg)[0]
190 }
191 argv1[len(argv)] = nil
192
193 env1 := make([]*byte, len(envv)+1)
194 for i, env := range envv {
195 env1[i] = &cstring(env)[0]
196 }
197 env1[len(envv)] = nil
198
199 fail := int(libc_execve(&argv0[0], &argv1[0], &env1[0]))
200 if fail < 0 {
201 err = getErrno()
202 }
203 return
204 }
205
206 func Truncate(path string, length int64) (err error) {
207 data := cstring(path)
208 fail := int(libc_truncate(&data[0], length))
209 if fail < 0 {
210 err = getErrno()
211 }
212 return
213 }
214
215 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
216
217 func Kill(pid int, sig Signal) (err error) {
218 return ENOSYS // TODO
219 }
220
221 type SysProcAttr struct{}
222
223 // TODO
224 type WaitStatus uint32
225
226 func (w WaitStatus) Exited() bool { return false }
227 func (w WaitStatus) ExitStatus() int { return 0 }
228 func (w WaitStatus) Signaled() bool { return false }
229 func (w WaitStatus) Signal() Signal { return 0 }
230 func (w WaitStatus) CoreDump() bool { return false }
231 func (w WaitStatus) Stopped() bool { return false }
232 func (w WaitStatus) Continued() bool { return false }
233 func (w WaitStatus) StopSignal() Signal { return 0 }
234 func (w WaitStatus) TrapCause() int { return 0 }
235
236 // Purely here for compatibility.
237 type Rusage struct {
238 }
239
240 // since rusage is quite a big struct and we stub it out anyway no need to define it here
241 func Wait4(pid int, wstatus *WaitStatus, options int, rusage uintptr) (wpid int, err error) {
242 return 0, ENOSYS // TODO
243 }
244
245 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
246 addr := libc_mmap(nil, uintptr(length), int32(prot), int32(flags), int32(fd), uintptr(offset))
247 if addr == unsafe.Pointer(^uintptr(0)) {
248 return nil, getErrno()
249 }
250 return (*[1 << 30]byte)(addr)[:length:length], nil
251 }
252
253 func Munmap(b []byte) (err error) {
254 errCode := libc_munmap(unsafe.Pointer(&b[0]), uintptr(len(b)))
255 if errCode != 0 {
256 err = getErrno()
257 }
258 return err
259 }
260
261 func Mprotect(b []byte, prot int) (err error) {
262 errCode := libc_mprotect(unsafe.Pointer(&b[0]), uintptr(len(b)), int32(prot))
263 if errCode != 0 {
264 err = getErrno()
265 }
266 return
267 }
268
269 // BytePtrFromString returns a pointer to a NUL-terminated array of
270 // bytes containing the text of s. If s contains a NUL byte at any
271 // location, it returns (nil, EINVAL).
272 func BytePtrFromString(s string) (*byte, error) {
273 for i := 0; i < len(s); i++ {
274 if s[i] == 0 {
275 return nil, EINVAL
276 }
277 }
278 return &cstring(s)[0], nil
279 }
280
281 // cstring converts a Go string to a C string.
282 func cstring(s string) []byte {
283 data := make([]byte, len(s)+1)
284 copy(data, s)
285 // final byte should be zero from the initial allocation
286 return data
287 }
288
289 func splitSlice(p []byte) (buf *byte, len uintptr) {
290 slice := (*sliceHeader)(unsafe.Pointer(&p))
291 return slice.buf, slice.len
292 }
293
294 // These two functions are provided by the runtime.
295 func runtimeSetenv(key, value string)
296 func runtimeUnsetenv(key string)
297
298 //export strlen
299 func libc_strlen(ptr unsafe.Pointer) uintptr
300
301 // ssize_t write(int fd, const void *buf, size_t count)
302 //
303 //export write
304 func libc_write(fd int32, buf *byte, count uint) int
305
306 // char *getenv(const char *name);
307 //
308 //export getenv
309 func libc_getenv(name *byte) *byte
310
311 // ssize_t read(int fd, void *buf, size_t count);
312 //
313 //export read
314 func libc_read(fd int32, buf *byte, count uint) int
315
316 // ssize_t pread(int fd, void *buf, size_t count, off_t offset);
317 //
318 //export pread
319 func libc_pread(fd int32, buf *byte, count uint, offset int64) int
320
321 // ssize_t pwrite(int fd, void *buf, size_t count, off_t offset);
322 //
323 //export pwrite
324 func libc_pwrite(fd int32, buf *byte, count uint, offset int64) int
325
326 // ssize_t lseek(int fd, off_t offset, int whence);
327 //
328 //export lseek
329 func libc_lseek(fd int32, offset int64, whence int) int64
330
331 // int close(int fd)
332 //
333 //export close
334 func libc_close(fd int32) int32
335
336 // int dup(int fd)
337 //
338 //export dup
339 func libc_dup(fd int32) int32
340
341 // void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
342 //
343 //export mmap
344 func libc_mmap(addr unsafe.Pointer, length uintptr, prot, flags, fd int32, offset uintptr) unsafe.Pointer
345
346 // int munmap(void *addr, size_t length);
347 //
348 //export munmap
349 func libc_munmap(addr unsafe.Pointer, length uintptr) int32
350
351 // int mprotect(void *addr, size_t len, int prot);
352 //
353 //export mprotect
354 func libc_mprotect(addr unsafe.Pointer, len uintptr, prot int32) int32
355
356 // int chdir(const char *pathname, mode_t mode);
357 //
358 //export chdir
359 func libc_chdir(pathname *byte) int32
360
361 // int chmod(const char *pathname, mode_t mode);
362 //
363 //export chmod
364 func libc_chmod(pathname *byte, mode uint32) int32
365
366 // int chown(const char *pathname, uid_t owner, gid_t group);
367 //
368 //export chown
369 func libc_chown(pathname *byte, owner, group int) int32
370
371 // int mkdir(const char *pathname, mode_t mode);
372 //
373 //export mkdir
374 func libc_mkdir(pathname *byte, mode uint32) int32
375
376 // int rmdir(const char *pathname);
377 //
378 //export rmdir
379 func libc_rmdir(pathname *byte) int32
380
381 // int rename(const char *from, *to);
382 //
383 //export rename
384 func libc_rename(from, to *byte) int32
385
386 // int symlink(const char *from, *to);
387 //
388 //export symlink
389 func libc_symlink(from, to *byte) int32
390
391 // int link(const char *oldname, *newname);
392 //
393 //export link
394 func libc_link(oldname, newname *byte) int32
395
396 // int fsync(int fd);
397 //
398 //export fsync
399 func libc_fsync(fd int32) int32
400
401 // ssize_t readlink(const char *path, void *buf, size_t count);
402 //
403 //export readlink
404 func libc_readlink(path *byte, buf *byte, count uint) int
405
406 // int unlink(const char *pathname);
407 //
408 //export unlink
409 func libc_unlink(pathname *byte) int32
410
411 // pid_t fork(void);
412 //
413 //export fork
414 func libc_fork() int32
415
416 // int execve(const char *filename, char *const argv[], char *const envp[]);
417 //
418 //export execve
419 func libc_execve(filename *byte, argv **byte, envp **byte) int
420
421 // int truncate(const char *path, off_t length);
422 //
423 //export truncate
424 func libc_truncate(path *byte, length int64) int32
425