@ai-ecoverse/slicc-kernel 1.98.4 → 1.99.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -1
- package/dist/kernel-worker.js +275 -27
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +89 -14
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +275 -27
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +89 -14
- package/dist/process-worker.js.map +4 -4
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -1038,6 +1038,7 @@ function kernelFdKind(file) {
|
|
|
1038
1038
|
}
|
|
1039
1039
|
var FdTable = class _FdTable {
|
|
1040
1040
|
static MAX_FDS = 1024;
|
|
1041
|
+
handles;
|
|
1041
1042
|
fds = /* @__PURE__ */ new Map();
|
|
1042
1043
|
cloexec = /* @__PURE__ */ new Set();
|
|
1043
1044
|
status = /* @__PURE__ */ new Map();
|
|
@@ -1134,6 +1135,7 @@ var FdTable = class _FdTable {
|
|
|
1134
1135
|
for (const [fd, file] of this.fds) child.fds.set(fd, file.retain());
|
|
1135
1136
|
for (const fd of this.cloexec) child.cloexec.add(fd);
|
|
1136
1137
|
for (const [fd, flags2] of this.status) child.status.set(fd, flags2);
|
|
1138
|
+
child.handles = this.handles?.fork();
|
|
1137
1139
|
return child;
|
|
1138
1140
|
}
|
|
1139
1141
|
async closeAll() {
|
|
@@ -1141,6 +1143,7 @@ var FdTable = class _FdTable {
|
|
|
1141
1143
|
this.fds.clear();
|
|
1142
1144
|
this.cloexec.clear();
|
|
1143
1145
|
this.status.clear();
|
|
1146
|
+
this.handles?.clear();
|
|
1144
1147
|
await Promise.allSettled(files.map((file) => Promise.resolve().then(() => file.release())));
|
|
1145
1148
|
}
|
|
1146
1149
|
};
|
|
@@ -3269,7 +3272,7 @@ function serveClient(port, host) {
|
|
|
3269
3272
|
case "umount":
|
|
3270
3273
|
return { result: await l.umountAs(clientCred(self), req.target).then(() => true) };
|
|
3271
3274
|
case "mounts":
|
|
3272
|
-
return { result: l.mounts.
|
|
3275
|
+
return { result: l.mounts.listed() };
|
|
3273
3276
|
case "dial":
|
|
3274
3277
|
return dialFor(l, req, watches);
|
|
3275
3278
|
case "serve-cdp":
|
|
@@ -7476,6 +7479,18 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7476
7479
|
};
|
|
7477
7480
|
}
|
|
7478
7481
|
|
|
7482
|
+
// src/fs/dev-removal.ts
|
|
7483
|
+
var SHM = "/dev/shm";
|
|
7484
|
+
function inDevTree(path) {
|
|
7485
|
+
if (path.startsWith(`${SHM}/`)) return false;
|
|
7486
|
+
return path === "/dev" || path.startsWith("/dev/");
|
|
7487
|
+
}
|
|
7488
|
+
function devRemoval(path, cred) {
|
|
7489
|
+
if (!inDevTree(path)) return void 0;
|
|
7490
|
+
if (cred && cred.euid !== 0) return "EACCES";
|
|
7491
|
+
return path === "/dev" ? "EBUSY" : "EPERM";
|
|
7492
|
+
}
|
|
7493
|
+
|
|
7479
7494
|
// src/fs/fresh-modules.ts
|
|
7480
7495
|
var MAGIC = [0, 97, 115, 109];
|
|
7481
7496
|
var MAX_FRESH = 65536;
|
|
@@ -8602,6 +8617,7 @@ var MountTable = class {
|
|
|
8602
8617
|
devices = 0;
|
|
8603
8618
|
pending = /* @__PURE__ */ new Set();
|
|
8604
8619
|
notes = /* @__PURE__ */ new Map();
|
|
8620
|
+
system = /* @__PURE__ */ new Set();
|
|
8605
8621
|
deps;
|
|
8606
8622
|
constructor(deps) {
|
|
8607
8623
|
this.deps = deps;
|
|
@@ -8623,6 +8639,13 @@ var MountTable = class {
|
|
|
8623
8639
|
const noted = [...this.notes.values()].filter((note) => !this.mounts.has(note.target));
|
|
8624
8640
|
return [...mounted, ...noted.map((note) => ({ ...note, options: { ...note.options } }))];
|
|
8625
8641
|
}
|
|
8642
|
+
listed() {
|
|
8643
|
+
return this.list().filter((entry) => !this.system.has(entry.target));
|
|
8644
|
+
}
|
|
8645
|
+
async mountSystem(spec, fs) {
|
|
8646
|
+
await this.mount(spec, fs);
|
|
8647
|
+
this.system.add(normalizePath(spec.target));
|
|
8648
|
+
}
|
|
8626
8649
|
note(spec, state, error) {
|
|
8627
8650
|
const target = normalizePath(spec.target);
|
|
8628
8651
|
this.notes.set(target, {
|
|
@@ -8729,6 +8752,7 @@ var MountTable = class {
|
|
|
8729
8752
|
if (!mount && this.notes.delete(at)) return;
|
|
8730
8753
|
if (!mount) throw errnoError("EINVAL", `${at} is not mounted`);
|
|
8731
8754
|
if (!detach && this.deps.busy(at)) throw errnoError("EBUSY", `${at} has open files`);
|
|
8755
|
+
this.system.delete(at);
|
|
8732
8756
|
this.notes.delete(at);
|
|
8733
8757
|
this.mounts.delete(at);
|
|
8734
8758
|
this.deps.reshaped?.();
|
|
@@ -9637,16 +9661,6 @@ var MountFs = class _MountFs {
|
|
|
9637
9661
|
}
|
|
9638
9662
|
};
|
|
9639
9663
|
|
|
9640
|
-
// src/fs/dev-removal.ts
|
|
9641
|
-
function inDevTree(path) {
|
|
9642
|
-
return path === "/dev" || path.startsWith("/dev/");
|
|
9643
|
-
}
|
|
9644
|
-
function devRemoval(path, cred) {
|
|
9645
|
-
if (!inDevTree(path)) return void 0;
|
|
9646
|
-
if (cred && cred.euid !== 0) return "EACCES";
|
|
9647
|
-
return path === "/dev" ? "EBUSY" : "EPERM";
|
|
9648
|
-
}
|
|
9649
|
-
|
|
9650
9664
|
// src/realm/sync-fs-token-registry.ts
|
|
9651
9665
|
var registry = /* @__PURE__ */ new Map();
|
|
9652
9666
|
function mintSyncFsToken(entry) {
|
|
@@ -11075,7 +11089,7 @@ var PATH_OPS = new Set(SYNC_FS_OPS);
|
|
|
11075
11089
|
var EARLY_WHOLE_FILE = 64 * 1024;
|
|
11076
11090
|
|
|
11077
11091
|
// src/version.ts
|
|
11078
|
-
var KERNEL_VERSION = true ? "1.
|
|
11092
|
+
var KERNEL_VERSION = true ? "1.99.1" : "0.0.0-dev";
|
|
11079
11093
|
var OS_RELEASE = "6.0.0-slicc";
|
|
11080
11094
|
function procVersion() {
|
|
11081
11095
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -14173,6 +14187,206 @@ async function waitReady(fds, read, write, deadline, interrupted3) {
|
|
|
14173
14187
|
}
|
|
14174
14188
|
}
|
|
14175
14189
|
|
|
14190
|
+
// src/kernel/sem.ts
|
|
14191
|
+
var SEM_VALUE_MAX = 2147483647;
|
|
14192
|
+
var SEM_NAMES_MAX = 4096;
|
|
14193
|
+
var SEM_HANDLES_MAX = 256;
|
|
14194
|
+
var NAME_MAX = 251;
|
|
14195
|
+
var TIMER_MAX_MS = 2147483647;
|
|
14196
|
+
var SEM_OPS = [
|
|
14197
|
+
"sem-open",
|
|
14198
|
+
"sem-close",
|
|
14199
|
+
"sem-unlink",
|
|
14200
|
+
"sem-post",
|
|
14201
|
+
"sem-wait",
|
|
14202
|
+
"sem-getvalue"
|
|
14203
|
+
];
|
|
14204
|
+
var Semaphore = class {
|
|
14205
|
+
value;
|
|
14206
|
+
uid;
|
|
14207
|
+
gid;
|
|
14208
|
+
mode;
|
|
14209
|
+
waiters = [];
|
|
14210
|
+
constructor(value, uid, gid, mode) {
|
|
14211
|
+
this.value = value;
|
|
14212
|
+
this.uid = uid;
|
|
14213
|
+
this.gid = gid;
|
|
14214
|
+
this.mode = mode;
|
|
14215
|
+
}
|
|
14216
|
+
post() {
|
|
14217
|
+
const next2 = this.waiters.shift();
|
|
14218
|
+
if (next2) next2.grant();
|
|
14219
|
+
else if (this.value >= SEM_VALUE_MAX) throw new KernelError("EOVERFLOW");
|
|
14220
|
+
else this.value++;
|
|
14221
|
+
}
|
|
14222
|
+
take() {
|
|
14223
|
+
if (this.value === 0) return false;
|
|
14224
|
+
this.value--;
|
|
14225
|
+
return true;
|
|
14226
|
+
}
|
|
14227
|
+
wait(signal, timeoutMs) {
|
|
14228
|
+
if (this.take()) return Promise.resolve(true);
|
|
14229
|
+
if (signal.aborted) return Promise.reject(new KernelError("EINTR"));
|
|
14230
|
+
return new Promise((resolve2, reject) => {
|
|
14231
|
+
const deadline = timeoutMs < 0 ? Number.POSITIVE_INFINITY : performance.now() + timeoutMs;
|
|
14232
|
+
let timer;
|
|
14233
|
+
const leave = () => {
|
|
14234
|
+
const at = this.waiters.indexOf(waiter);
|
|
14235
|
+
if (at >= 0) this.waiters.splice(at, 1);
|
|
14236
|
+
clearTimeout(timer);
|
|
14237
|
+
signal.removeEventListener("abort", abort);
|
|
14238
|
+
};
|
|
14239
|
+
const waiter = {
|
|
14240
|
+
grant: () => {
|
|
14241
|
+
leave();
|
|
14242
|
+
resolve2(true);
|
|
14243
|
+
}
|
|
14244
|
+
};
|
|
14245
|
+
const abort = () => {
|
|
14246
|
+
leave();
|
|
14247
|
+
reject(new KernelError("EINTR"));
|
|
14248
|
+
};
|
|
14249
|
+
const expire = () => {
|
|
14250
|
+
const left = deadline - performance.now();
|
|
14251
|
+
if (left > 0) {
|
|
14252
|
+
timer = setTimeout(expire, Math.min(left, TIMER_MAX_MS));
|
|
14253
|
+
return;
|
|
14254
|
+
}
|
|
14255
|
+
leave();
|
|
14256
|
+
resolve2(false);
|
|
14257
|
+
};
|
|
14258
|
+
this.waiters.push(waiter);
|
|
14259
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
14260
|
+
if (deadline !== Number.POSITIVE_INFINITY) {
|
|
14261
|
+
timer = setTimeout(expire, Math.min(timeoutMs, TIMER_MAX_MS));
|
|
14262
|
+
}
|
|
14263
|
+
});
|
|
14264
|
+
}
|
|
14265
|
+
};
|
|
14266
|
+
var SemTable = class {
|
|
14267
|
+
names = /* @__PURE__ */ new Map();
|
|
14268
|
+
limit;
|
|
14269
|
+
constructor(limit = SEM_NAMES_MAX) {
|
|
14270
|
+
this.limit = limit;
|
|
14271
|
+
}
|
|
14272
|
+
open(name2, create, exclusive, make, check, adopt) {
|
|
14273
|
+
const found = this.names.get(name2);
|
|
14274
|
+
if (found) {
|
|
14275
|
+
if (create && exclusive) throw new KernelError("EEXIST");
|
|
14276
|
+
check(found);
|
|
14277
|
+
return adopt(found);
|
|
14278
|
+
}
|
|
14279
|
+
if (!create) throw new KernelError("ENOENT");
|
|
14280
|
+
if (this.names.size >= this.limit) throw new KernelError("ENOSPC");
|
|
14281
|
+
const sem = make();
|
|
14282
|
+
const handle = adopt(sem);
|
|
14283
|
+
this.names.set(name2, sem);
|
|
14284
|
+
return handle;
|
|
14285
|
+
}
|
|
14286
|
+
unlink(name2, check) {
|
|
14287
|
+
const found = this.names.get(name2);
|
|
14288
|
+
if (!found) throw new KernelError("ENOENT");
|
|
14289
|
+
check(found);
|
|
14290
|
+
this.names.delete(name2);
|
|
14291
|
+
}
|
|
14292
|
+
};
|
|
14293
|
+
var SemHandles = class _SemHandles {
|
|
14294
|
+
byHandle = /* @__PURE__ */ new Map();
|
|
14295
|
+
next = 1;
|
|
14296
|
+
add(sem) {
|
|
14297
|
+
for (const [handle2, entry] of this.byHandle) {
|
|
14298
|
+
if (entry.sem === sem) {
|
|
14299
|
+
entry.opens++;
|
|
14300
|
+
return handle2;
|
|
14301
|
+
}
|
|
14302
|
+
}
|
|
14303
|
+
if (this.byHandle.size >= SEM_HANDLES_MAX) throw new KernelError("EMFILE");
|
|
14304
|
+
const handle = this.next++;
|
|
14305
|
+
this.byHandle.set(handle, { sem, opens: 1 });
|
|
14306
|
+
return handle;
|
|
14307
|
+
}
|
|
14308
|
+
get(handle) {
|
|
14309
|
+
const entry = this.byHandle.get(handle);
|
|
14310
|
+
if (!entry) throw new KernelError("EINVAL");
|
|
14311
|
+
return entry.sem;
|
|
14312
|
+
}
|
|
14313
|
+
close(handle) {
|
|
14314
|
+
const entry = this.byHandle.get(handle);
|
|
14315
|
+
if (!entry) throw new KernelError("EINVAL");
|
|
14316
|
+
if (--entry.opens === 0) this.byHandle.delete(handle);
|
|
14317
|
+
}
|
|
14318
|
+
fork() {
|
|
14319
|
+
const child = new _SemHandles();
|
|
14320
|
+
child.next = this.next;
|
|
14321
|
+
for (const [handle, entry] of this.byHandle) child.byHandle.set(handle, { ...entry });
|
|
14322
|
+
return child;
|
|
14323
|
+
}
|
|
14324
|
+
clear() {
|
|
14325
|
+
this.byHandle.clear();
|
|
14326
|
+
}
|
|
14327
|
+
};
|
|
14328
|
+
function semName(raw) {
|
|
14329
|
+
const name2 = raw.replace(/^\/+/, "");
|
|
14330
|
+
if (name2 === "" || name2.includes("/") || name2 === "." || name2 === "..") {
|
|
14331
|
+
throw new KernelError("EINVAL");
|
|
14332
|
+
}
|
|
14333
|
+
if (new TextEncoder().encode(name2).length > NAME_MAX) throw new KernelError("ENAMETOOLONG");
|
|
14334
|
+
return name2;
|
|
14335
|
+
}
|
|
14336
|
+
var ok2 = (json5) => json5 === void 0 ? { ok: true, kind: "void" } : { ok: true, kind: "json", json: json5 };
|
|
14337
|
+
async function semSyscall(req, proc) {
|
|
14338
|
+
const { table, handles, cred } = proc;
|
|
14339
|
+
if (!table) throw new KernelError("ENOSYS");
|
|
14340
|
+
const { denied: denied2 } = proc;
|
|
14341
|
+
const shown = (name2) => `/dev/shm/sem.${name2}`;
|
|
14342
|
+
const opens = (name2) => (sem) => {
|
|
14343
|
+
const perm = { uid: sem.uid, gid: sem.gid, mode: sem.mode };
|
|
14344
|
+
if (denied2 && !permits(cred, perm, R_OK | W_OK, false)) denied2("sem_open", shown(name2));
|
|
14345
|
+
};
|
|
14346
|
+
const unlinks = (name2) => (sem) => {
|
|
14347
|
+
if (denied2 && cred.euid !== 0 && cred.euid !== sem.uid) denied2("sem_unlink", shown(name2));
|
|
14348
|
+
};
|
|
14349
|
+
switch (req.op) {
|
|
14350
|
+
case "sem-open": {
|
|
14351
|
+
if (req.value < 0 || req.value > SEM_VALUE_MAX) throw new KernelError("EINVAL");
|
|
14352
|
+
const name2 = semName(req.name);
|
|
14353
|
+
const mode = req.mode & 511 & ~proc.umask;
|
|
14354
|
+
return ok2(
|
|
14355
|
+
table.open(
|
|
14356
|
+
name2,
|
|
14357
|
+
req.create,
|
|
14358
|
+
req.exclusive,
|
|
14359
|
+
() => new Semaphore(req.value, cred.euid, cred.egid, mode),
|
|
14360
|
+
opens(name2),
|
|
14361
|
+
(sem) => handles.add(sem)
|
|
14362
|
+
)
|
|
14363
|
+
);
|
|
14364
|
+
}
|
|
14365
|
+
case "sem-close":
|
|
14366
|
+
handles.close(req.handle);
|
|
14367
|
+
return ok2();
|
|
14368
|
+
case "sem-unlink": {
|
|
14369
|
+
const name2 = semName(req.name);
|
|
14370
|
+
table.unlink(name2, unlinks(name2));
|
|
14371
|
+
return ok2();
|
|
14372
|
+
}
|
|
14373
|
+
case "sem-post":
|
|
14374
|
+
handles.get(req.handle).post();
|
|
14375
|
+
return ok2();
|
|
14376
|
+
case "sem-getvalue":
|
|
14377
|
+
return ok2(handles.get(req.handle).value);
|
|
14378
|
+
case "sem-wait": {
|
|
14379
|
+
const sem = handles.get(req.handle);
|
|
14380
|
+
if (sem.take()) return ok2();
|
|
14381
|
+
if (req.how === "try") throw new KernelError("EAGAIN");
|
|
14382
|
+
if (req.how === "timed" && req.timeoutMs === 0) throw new KernelError("ETIMEDOUT");
|
|
14383
|
+
const got = await sem.wait(proc.blocking(), req.how === "block" ? -1 : req.timeoutMs);
|
|
14384
|
+
if (!got) throw new KernelError("ETIMEDOUT");
|
|
14385
|
+
return ok2();
|
|
14386
|
+
}
|
|
14387
|
+
}
|
|
14388
|
+
}
|
|
14389
|
+
|
|
14176
14390
|
// src/kernel/net/datagram-wire.ts
|
|
14177
14391
|
function encodeReceived(got) {
|
|
14178
14392
|
const host = new TextEncoder().encode(got.host);
|
|
@@ -14219,20 +14433,20 @@ function dgramAt(fds, fd) {
|
|
|
14219
14433
|
if (!(file instanceof KernelDgram)) throw new KernelError("EOPNOTSUPP");
|
|
14220
14434
|
return file;
|
|
14221
14435
|
}
|
|
14222
|
-
var
|
|
14436
|
+
var ok3 = (json5) => json5 === void 0 ? { ok: true, kind: "void" } : { ok: true, kind: "json", json: json5 };
|
|
14223
14437
|
async function socketSyscall(req, proc) {
|
|
14224
14438
|
const { fds, net } = proc;
|
|
14225
14439
|
switch (req.op) {
|
|
14226
14440
|
case "sock-open": {
|
|
14227
14441
|
if (req.type === "dgram" && req.domain !== "inet") throw new KernelError("EPROTONOSUPPORT");
|
|
14228
14442
|
const file = req.type === "dgram" ? new KernelDgram(net) : net.socket(req.domain);
|
|
14229
|
-
return
|
|
14443
|
+
return ok3(fds.install(new OpenFile(file), 3));
|
|
14230
14444
|
}
|
|
14231
14445
|
case "sock-pair": {
|
|
14232
14446
|
const [a, b] = KernelSocket.pair(net, req.domain, proc.cred?.());
|
|
14233
14447
|
const first = fds.install(new OpenFile(a), 3);
|
|
14234
14448
|
try {
|
|
14235
|
-
return
|
|
14449
|
+
return ok3([first, fds.install(new OpenFile(b), 3)]);
|
|
14236
14450
|
} catch (e) {
|
|
14237
14451
|
await Promise.resolve(fds.close(first));
|
|
14238
14452
|
throw e;
|
|
@@ -14240,32 +14454,32 @@ async function socketSyscall(req, proc) {
|
|
|
14240
14454
|
}
|
|
14241
14455
|
case "sock-bind":
|
|
14242
14456
|
anySocketAt(fds, req.fd).bind(req.addr);
|
|
14243
|
-
return
|
|
14457
|
+
return ok3();
|
|
14244
14458
|
case "sock-listen":
|
|
14245
14459
|
socketAt(fds, req.fd).listen(req.backlog, proc.cred?.());
|
|
14246
|
-
return
|
|
14460
|
+
return ok3();
|
|
14247
14461
|
case "sock-accept":
|
|
14248
|
-
return
|
|
14462
|
+
return ok3(await accept(proc, req.fd, req.nonblock));
|
|
14249
14463
|
case "sock-connect":
|
|
14250
14464
|
return connect(req, proc);
|
|
14251
14465
|
case "sock-shutdown":
|
|
14252
14466
|
anySocketAt(fds, req.fd).shutdown(req.how);
|
|
14253
|
-
return
|
|
14467
|
+
return ok3();
|
|
14254
14468
|
case "sock-name": {
|
|
14255
14469
|
const socket = anySocketAt(fds, req.fd);
|
|
14256
14470
|
const addr = req.peer ? socket.peer : socket.local;
|
|
14257
14471
|
if (req.peer && !addr) throw new KernelError("ENOTCONN");
|
|
14258
|
-
return
|
|
14472
|
+
return ok3(addr ?? unnamed(socket instanceof KernelDgram ? "inet" : socket.domain));
|
|
14259
14473
|
}
|
|
14260
14474
|
case "sock-getopt":
|
|
14261
|
-
return
|
|
14475
|
+
return ok3(anySocketAt(fds, req.fd).getOption(req.level, req.name));
|
|
14262
14476
|
case "sock-setopt":
|
|
14263
14477
|
anySocketAt(fds, req.fd).setOption(req.level, req.name, req.value);
|
|
14264
|
-
return
|
|
14478
|
+
return ok3();
|
|
14265
14479
|
case "sock-resolve": {
|
|
14266
14480
|
const addresses = await proc.resolve(req.name, req.family, () => proc.blocking());
|
|
14267
14481
|
if (addresses.length === 0) throw new KernelError("ENOENT");
|
|
14268
|
-
return
|
|
14482
|
+
return ok3(addresses);
|
|
14269
14483
|
}
|
|
14270
14484
|
default:
|
|
14271
14485
|
return datagram(req, proc);
|
|
@@ -14275,7 +14489,7 @@ async function connect(req, proc) {
|
|
|
14275
14489
|
const target = anySocketAt(proc.fds, req.fd);
|
|
14276
14490
|
if (target instanceof KernelDgram) {
|
|
14277
14491
|
target.connectTo(req.addr);
|
|
14278
|
-
return
|
|
14492
|
+
return ok3();
|
|
14279
14493
|
}
|
|
14280
14494
|
const stamp = proc.net.facadeAt(req.addr) && await proc.stamp?.();
|
|
14281
14495
|
const dialing = target.connect(req.addr, true, proc.cred?.(), stamp || void 0);
|
|
@@ -14284,13 +14498,13 @@ async function connect(req, proc) {
|
|
|
14284
14498
|
throw new KernelError("EINPROGRESS");
|
|
14285
14499
|
}
|
|
14286
14500
|
if (dialing !== void 0) await interruptible2(dialing, proc.blocking());
|
|
14287
|
-
return
|
|
14501
|
+
return ok3();
|
|
14288
14502
|
}
|
|
14289
14503
|
async function datagram(req, proc) {
|
|
14290
14504
|
const dgram = dgramAt(proc.fds, req.fd);
|
|
14291
14505
|
if (req.op === "sock-sendto") {
|
|
14292
14506
|
if (req.nonblock && !pollFile(dgram).writable) throw new KernelError("EAGAIN");
|
|
14293
|
-
return
|
|
14507
|
+
return ok3(await dgram.send(req.body, req.addr));
|
|
14294
14508
|
}
|
|
14295
14509
|
const ready2 = pollFile(dgram).readable;
|
|
14296
14510
|
if (req.nonblock && !ready2) throw new KernelError("EAGAIN");
|
|
@@ -15056,6 +15270,9 @@ function isHttpSyscall(req) {
|
|
|
15056
15270
|
function isSocketSyscall(req) {
|
|
15057
15271
|
return req.op.startsWith("sock-");
|
|
15058
15272
|
}
|
|
15273
|
+
function isSemSyscall(req) {
|
|
15274
|
+
return req.op.startsWith("sem-");
|
|
15275
|
+
}
|
|
15059
15276
|
function isEpollSyscall(req) {
|
|
15060
15277
|
return EPOLL_OPS.includes(req.op);
|
|
15061
15278
|
}
|
|
@@ -15150,6 +15367,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
15150
15367
|
"sig-pause",
|
|
15151
15368
|
...SOCKET_OPS,
|
|
15152
15369
|
...EPOLL_OPS,
|
|
15370
|
+
...SEM_OPS,
|
|
15153
15371
|
...HTTP_OPS,
|
|
15154
15372
|
...PTY_OPS,
|
|
15155
15373
|
...HOST_OPS
|
|
@@ -15382,6 +15600,7 @@ var WasmProcess = class {
|
|
|
15382
15600
|
if (isTtySyscall(req)) return this.ttySyscall(req);
|
|
15383
15601
|
if (isJobSyscall(req)) return this.jobSyscall(req);
|
|
15384
15602
|
if (isSocketSyscall(req)) return await this.socketSyscall(req, cancelled);
|
|
15603
|
+
if (isSemSyscall(req)) return await this.semSyscall(req, cancelled);
|
|
15385
15604
|
if (isEpollSyscall(req)) {
|
|
15386
15605
|
return await epollSyscall(req, {
|
|
15387
15606
|
fds: this.fds,
|
|
@@ -16101,6 +16320,20 @@ var WasmProcess = class {
|
|
|
16101
16320
|
if (!http) return Promise.resolve({ ok: false, errno: "ENETUNREACH", message: NO_TRANSPORT });
|
|
16102
16321
|
return http.syscall(req);
|
|
16103
16322
|
}
|
|
16323
|
+
semSyscall(req, cancelled) {
|
|
16324
|
+
const g = this.guarded();
|
|
16325
|
+
const known = this.fds.handles;
|
|
16326
|
+
const handles = known instanceof SemHandles ? known : new SemHandles();
|
|
16327
|
+
this.fds.handles = handles;
|
|
16328
|
+
return semSyscall(req, {
|
|
16329
|
+
table: this.options.sems,
|
|
16330
|
+
handles,
|
|
16331
|
+
cred: this.cred,
|
|
16332
|
+
denied: g ? (op, path) => deny(g, op, path) : void 0,
|
|
16333
|
+
umask: this.umask,
|
|
16334
|
+
blocking: () => this.blockingSignal(cancelled)
|
|
16335
|
+
});
|
|
16336
|
+
}
|
|
16104
16337
|
socketSyscall(req, cancelled) {
|
|
16105
16338
|
this.net ??= this.options.net ?? new LoopbackNet();
|
|
16106
16339
|
const resolver = this.options.resolver ?? HOSTS_ONLY;
|
|
@@ -16611,6 +16844,7 @@ function processOptions(opts, header4, hooks, created3) {
|
|
|
16611
16844
|
net: opts.net,
|
|
16612
16845
|
http: opts.http,
|
|
16613
16846
|
locks: opts.locks,
|
|
16847
|
+
...opts.sems ? { sems: opts.sems } : {},
|
|
16614
16848
|
onReap: opts.onReap,
|
|
16615
16849
|
resolver: opts.resolver,
|
|
16616
16850
|
...notifiers(header4),
|
|
@@ -20084,6 +20318,9 @@ var NOT_EXECUTABLE = 126;
|
|
|
20084
20318
|
var DECIDE_MS = 100;
|
|
20085
20319
|
var INIT_PID = 1;
|
|
20086
20320
|
var SHARED_DIRS = ["/tmp", "/home"];
|
|
20321
|
+
function unref2(port) {
|
|
20322
|
+
port.unref?.();
|
|
20323
|
+
}
|
|
20087
20324
|
var LAYOUT = [
|
|
20088
20325
|
["/", 493],
|
|
20089
20326
|
["/root", 448],
|
|
@@ -20272,6 +20509,7 @@ var Launcher = class {
|
|
|
20272
20509
|
sudoer;
|
|
20273
20510
|
jobs = new JobTable();
|
|
20274
20511
|
locks = new LockTable();
|
|
20512
|
+
sems = new SemTable();
|
|
20275
20513
|
settling = new SettlingChildren((pid) => this.jobs.pgidOf(pid));
|
|
20276
20514
|
ptys = new PtyTable(
|
|
20277
20515
|
(tty, sig) => this.keySignal(tty, 0, sig, () => this.jobs.signalOwnedForeground(tty, sig)),
|
|
@@ -20293,6 +20531,7 @@ var Launcher = class {
|
|
|
20293
20531
|
pnpmMade;
|
|
20294
20532
|
pnpmEpoch = 0;
|
|
20295
20533
|
mounts;
|
|
20534
|
+
shmPorts = [];
|
|
20296
20535
|
createDriverWorker;
|
|
20297
20536
|
media;
|
|
20298
20537
|
onMountPending;
|
|
@@ -21130,6 +21369,7 @@ var Launcher = class {
|
|
|
21130
21369
|
net: this.net,
|
|
21131
21370
|
http: new HttpHandles(this.transport, pid, this.loopbackFor(pid)),
|
|
21132
21371
|
locks: this.locks,
|
|
21372
|
+
sems: this.sems,
|
|
21133
21373
|
resolver: this.resolver,
|
|
21134
21374
|
onReap: (child) => this.reaped(child, pid),
|
|
21135
21375
|
...req.fork ? { fork: req.fork } : {},
|
|
@@ -21556,6 +21796,7 @@ var Launcher = class {
|
|
|
21556
21796
|
},
|
|
21557
21797
|
{ owned: true }
|
|
21558
21798
|
);
|
|
21799
|
+
if (spec.target === SHM) this.shmPorts = [port1, port2];
|
|
21559
21800
|
return {
|
|
21560
21801
|
port: port1,
|
|
21561
21802
|
dispose: () => {
|
|
@@ -21658,6 +21899,12 @@ var Launcher = class {
|
|
|
21658
21899
|
this.pnpmStale();
|
|
21659
21900
|
return entry;
|
|
21660
21901
|
}
|
|
21902
|
+
async mountShm() {
|
|
21903
|
+
await this.base.mkdir(SHM, { recursive: true });
|
|
21904
|
+
await this.mounts.mountSystem({ type: "tmpfs", source: "shm", target: SHM }, this.fs);
|
|
21905
|
+
for (const port of this.shmPorts) unref2(port);
|
|
21906
|
+
await this.fs.chmod(SHM, 1023);
|
|
21907
|
+
}
|
|
21661
21908
|
async ownTmp() {
|
|
21662
21909
|
const real = await this.realLayoutPath("/tmp");
|
|
21663
21910
|
const st = real === void 0 ? void 0 : await this.base.lstat(real).catch(() => void 0);
|
|
@@ -21814,6 +22061,7 @@ var Launcher = class {
|
|
|
21814
22061
|
await this.resolvePrefixes();
|
|
21815
22062
|
for (const dir of SHARED_DIRS) await this.base.mkdir(dir, { recursive: true });
|
|
21816
22063
|
if (this.owners) await this.ownTmp();
|
|
22064
|
+
await this.mountShm();
|
|
21817
22065
|
await this.pnpmReady();
|
|
21818
22066
|
await this.users.ensure();
|
|
21819
22067
|
if (this.owners) await this.stampLayout();
|
|
@@ -23554,7 +23802,7 @@ async function createNodeKernel(options = {}) {
|
|
|
23554
23802
|
readFile: async (path) => launcher.fs.readFileBuffer(path),
|
|
23555
23803
|
mount: (spec) => guard2(() => launcher.mount(spec)),
|
|
23556
23804
|
umount: (target) => guard2(async () => launcher.umount(target)),
|
|
23557
|
-
mounts: async () => launcher.mounts.
|
|
23805
|
+
mounts: async () => launcher.mounts.listed(),
|
|
23558
23806
|
setRoutes: (routes) => guard2(async () => launcher.setRoutes(routes)),
|
|
23559
23807
|
updateTransportTraits: () => guard2(async () => launcher.updateTransportTraits()),
|
|
23560
23808
|
users: {
|