Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/libc/emscripten_syscall_stubs.c
6162 views
1
/*
2
* Copyright 2021 The Emscripten Authors. All rights reserved.
3
* Emscripten is available under two separate licenses, the MIT license and the
4
* University of Illinois/NCSA Open Source License. Both these licenses can be
5
* found in the LICENSE file.
6
*
7
* Unimplemented/dummy syscall implementations. These fall into 3 categories.
8
*
9
* 1. Fake it, use dummy/placeholder values and return success.
10
* 2. Fake it, as above but warn at runtime if called.
11
* 3. Return ENOSYS and warn at runtime if called.
12
*/
13
14
#include <errno.h>
15
#include <stdio.h>
16
#include <sys/types.h>
17
#include <unistd.h>
18
#include <syscall_arch.h>
19
#include <string.h>
20
#include <sys/resource.h>
21
#include <sys/stat.h>
22
#include <time.h>
23
#include <sys/utsname.h>
24
#include <emscripten/console.h>
25
#include <emscripten/version.h>
26
#include <emscripten/stack.h>
27
28
static int g_pid = 42;
29
static int g_pgid = 42;
30
static int g_ppid = 1;
31
static int g_sid = 42;
32
static mode_t g_umask = S_IWGRP | S_IWOTH;
33
34
#ifdef NDEBUG
35
#define REPORT(name)
36
#else
37
#define REPORT(name) \
38
emscripten_err("warning: unsupported syscall: __syscall_" #name);
39
#endif
40
41
#define UNIMPLEMENTED(name, args) \
42
weak int __syscall_##name args { \
43
REPORT(name); \
44
return -ENOSYS; \
45
}
46
47
#define STRINGIFY(s) #s
48
#define STR(s) STRINGIFY(s)
49
50
weak int __syscall_uname(intptr_t buf) {
51
if (!buf) {
52
return -EFAULT;
53
}
54
const char* full_version = STR(__EMSCRIPTEN_MAJOR__) "." \
55
STR(__EMSCRIPTEN_MINOR__) "." \
56
STR(__EMSCRIPTEN_TINY__);
57
58
struct utsname *utsname = (struct utsname *)buf;
59
60
strcpy(utsname->sysname, "Emscripten");
61
strcpy(utsname->nodename, "emscripten");
62
strcpy(utsname->release, full_version);
63
strcpy(utsname->version, "#1");
64
#ifdef __wasm64__
65
strcpy(utsname->machine, "wasm64");
66
#else
67
strcpy(utsname->machine, "wasm32");
68
#endif
69
return 0;
70
}
71
72
weak int __syscall_setpgid(int pid, int pgid) {
73
if (pid && pid != g_pid) {
74
return -ESRCH;
75
}
76
if (pgid && pgid != g_pgid) {
77
return -EPERM;
78
}
79
return 0;
80
}
81
82
weak int __syscall_sync() {
83
return 0;
84
}
85
86
weak int __syscall_getsid(int pid) {
87
if (pid && pid != g_pid) {
88
return -ESRCH;
89
}
90
return g_sid;
91
}
92
93
weak int __syscall_getpgid(int pid) {
94
if (pid && pid != g_pid) {
95
return -ESRCH;
96
}
97
return g_pgid;
98
}
99
100
weak int __syscall_getpid() {
101
return g_pid;
102
}
103
104
weak int __syscall_getppid() {
105
return g_ppid;
106
}
107
108
weak int __syscall_linkat(int olddirfd, intptr_t oldpath, int newdirfd, intptr_t newpath, int flags) {
109
return -EMLINK; // no hardlinks for us
110
}
111
112
weak int __syscall_getgroups32(int size, intptr_t list) {
113
if (size < 1) {
114
return -EINVAL;
115
}
116
((gid_t*)list)[0] = 0;
117
return 1;
118
}
119
120
weak int __syscall_setsid() {
121
return 0; // no-op
122
}
123
124
weak int __syscall_umask(int mask) {
125
int old = g_umask;
126
g_umask = mask;
127
return old;
128
}
129
130
struct kusage {
131
long utime_tv_sec;
132
long utime_tv_usec;
133
long stime_tv_sec;
134
long stime_tv_usec;
135
};
136
137
weak int __syscall_getrusage(int who, intptr_t usage) {
138
REPORT(getrusage);
139
struct kusage *u = (struct kusage*)usage;
140
u->utime_tv_sec = 1;
141
u->utime_tv_usec = 2;
142
u->stime_tv_sec = 3;
143
u->stime_tv_usec = 4;
144
return 0;
145
}
146
147
weak int __syscall_getpriority(int which, int who) {
148
return 0;
149
}
150
151
weak int __syscall_setpriority(int which, int who, int prio) {
152
return -EPERM;
153
}
154
155
weak int __syscall_setdomainname(intptr_t name, size_t size) {
156
return -EPERM;
157
}
158
159
weak int __syscall_getuid32(void) {
160
return 0;
161
}
162
163
weak int __syscall_getgid32(void) {
164
return 0;
165
}
166
167
weak int __syscall_geteuid32(void) {
168
return 0;
169
}
170
171
weak int __syscall_getegid32(void) {
172
return 0;
173
}
174
175
weak int __syscall_getresuid32(intptr_t ruid, intptr_t euid, intptr_t suid) {
176
*((uid_t *)ruid) = 0;
177
*((uid_t *)euid) = 0;
178
*((uid_t *)suid) = 0;
179
return 0;
180
}
181
182
weak int __syscall_getresgid32(intptr_t ruid, intptr_t euid, intptr_t suid) {
183
REPORT(getresgid32);
184
*((uid_t *)ruid) = 0;
185
*((uid_t *)euid) = 0;
186
*((uid_t *)suid) = 0;
187
return 0;
188
}
189
190
weak int __syscall_pause() {
191
REPORT(pause);
192
return -EINTR; // we can't pause
193
}
194
195
weak int __syscall_madvise(intptr_t addr, size_t length, int advice) {
196
REPORT(madvise);
197
// advice is welcome, but ignored
198
return 0;
199
}
200
201
weak int __syscall_mlock(intptr_t addr, size_t len) {
202
REPORT(mlock);
203
return 0;
204
}
205
206
weak int __syscall_munlock(intptr_t addr, size_t len) {
207
REPORT(munlock);
208
return 0;
209
}
210
211
weak int __syscall_mprotect(size_t addr, size_t len, int prot) {
212
REPORT(mprotect);
213
return 0; // let's not and say we did
214
}
215
216
weak int __syscall_mremap(intptr_t old_addr, size_t old_size, size_t new_size, int flags, intptr_t new_addr) {
217
REPORT(mremap);
218
return -ENOMEM; // never succeed
219
}
220
221
weak int __syscall_mlockall(int flags) {
222
REPORT(mlockall);
223
return 0;
224
}
225
226
weak int __syscall_munlockall() {
227
REPORT(munlockall);
228
return 0;
229
}
230
231
weak int __syscall_prlimit64(int pid, int resource, intptr_t new_limit, intptr_t old_limit) {
232
REPORT(prlimit64);
233
struct rlimit *old = (struct rlimit *)old_limit;
234
if (new_limit) {
235
return -EPERM;
236
}
237
if (old) {
238
if (resource == RLIMIT_NOFILE) {
239
// See FS.MAX_OPEN_FDS in src/lib/libfs.js
240
old->rlim_cur = 4096;
241
old->rlim_max = 4096;
242
} else if (resource == RLIMIT_STACK) {
243
uintptr_t end = emscripten_stack_get_end();
244
uintptr_t base = emscripten_stack_get_base();
245
246
old->rlim_cur = base - end;
247
// we can not change the stack size, so the maximum is the same as the current
248
old->rlim_max = base - end;
249
} else {
250
// Just report no limits
251
old->rlim_cur = RLIM_INFINITY;
252
old->rlim_max = RLIM_INFINITY;
253
}
254
}
255
return 0;
256
}
257
258
weak int __syscall_setsockopt(int sockfd, int level, int optname, intptr_t optval, size_t optlen, int dummy) {
259
REPORT(setsockopt);
260
return -ENOPROTOOPT; // The option is unknown at the level indicated.
261
}
262
263
UNIMPLEMENTED(acct, (intptr_t filename))
264
UNIMPLEMENTED(mincore, (intptr_t addr, size_t length, intptr_t vec))
265
UNIMPLEMENTED(pipe2, (intptr_t fds, int flags))
266
UNIMPLEMENTED(pselect6, (int nfds, intptr_t readfds, intptr_t writefds, intptr_t exceptfds, intptr_t timeout, intptr_t sigmaks))
267
UNIMPLEMENTED(ppoll, (intptr_t fds, int nfds, intptr_t timeout, intptr_t sigmask, int size))
268
UNIMPLEMENTED(recvmmsg, (int sockfd, intptr_t msgvec, size_t vlen, int flags, ...))
269
UNIMPLEMENTED(sendmmsg, (int sockfd, intptr_t msgvec, size_t vlen, int flags, ...))
270
UNIMPLEMENTED(shutdown, (int sockfd, int how, int dummy, int dummy2, int dummy3, int dummy4))
271
UNIMPLEMENTED(socketpair, (int domain, int type, int protocol, intptr_t fds, int dummy, int dummy2))
272
UNIMPLEMENTED(wait4,(int pid, intptr_t wstatus, int options, int rusage))
273
274