@ai-ecoverse/slicc-kernel 1.1.0 → 1.3.0
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 +42 -3
- package/dist/index.js +151 -2
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +2842 -463
- package/dist/kernel-worker.js.map +4 -4
- package/dist/process-worker.js +282 -29
- package/dist/process-worker.js.map +4 -4
- package/package.json +7 -6
package/dist/process-worker.js
CHANGED
|
@@ -55,6 +55,29 @@ var SIGNAL_BY_NAME = {
|
|
|
55
55
|
SIGCONT: SIG.CONT
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
// src/fs/types.ts
|
|
59
|
+
function normalizePath(path) {
|
|
60
|
+
const parts = [];
|
|
61
|
+
for (const part of path.split("/")) {
|
|
62
|
+
if (part === "" || part === ".") continue;
|
|
63
|
+
if (part === "..") parts.pop();
|
|
64
|
+
else parts.push(part);
|
|
65
|
+
}
|
|
66
|
+
return `/${parts.join("/")}`;
|
|
67
|
+
}
|
|
68
|
+
function inodeOf(path) {
|
|
69
|
+
let h1 = 3735928559;
|
|
70
|
+
let h2 = 1103547991;
|
|
71
|
+
for (let i = 0; i < path.length; i++) {
|
|
72
|
+
const c = path.charCodeAt(i);
|
|
73
|
+
h1 = Math.imul(h1 ^ c, 2654435761);
|
|
74
|
+
h2 = Math.imul(h2 ^ c, 1597334677);
|
|
75
|
+
}
|
|
76
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
77
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
78
|
+
return 4294967296 * (2097151 & h2) + (h1 >>> 0) || 1;
|
|
79
|
+
}
|
|
80
|
+
|
|
58
81
|
// src/realm/live-vfs-fs.ts
|
|
59
82
|
var ERRNO_BY_CODE = {
|
|
60
83
|
EACCES: 2,
|
|
@@ -90,8 +113,8 @@ function toErrno(Fs, err) {
|
|
|
90
113
|
return err;
|
|
91
114
|
}
|
|
92
115
|
const code = err?.code;
|
|
93
|
-
const
|
|
94
|
-
return new Fs.ErrnoError(
|
|
116
|
+
const errno2 = typeof code === "string" ? ERRNO_BY_CODE[code] ?? EIO : EIO;
|
|
117
|
+
return new Fs.ErrnoError(errno2);
|
|
95
118
|
}
|
|
96
119
|
function liveNodePath(node) {
|
|
97
120
|
const parts = [];
|
|
@@ -103,18 +126,6 @@ function liveNodePath(node) {
|
|
|
103
126
|
const root = node.mount.opts.root.replace(/\/+$/, "");
|
|
104
127
|
return parts.length === 0 ? root || "/" : `${root}/${parts.reverse().join("/")}`;
|
|
105
128
|
}
|
|
106
|
-
function inodeOf(path) {
|
|
107
|
-
let h1 = 3735928559;
|
|
108
|
-
let h2 = 1103547991;
|
|
109
|
-
for (let i = 0; i < path.length; i++) {
|
|
110
|
-
const c = path.charCodeAt(i);
|
|
111
|
-
h1 = Math.imul(h1 ^ c, 2654435761);
|
|
112
|
-
h2 = Math.imul(h2 ^ c, 1597334677);
|
|
113
|
-
}
|
|
114
|
-
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
115
|
-
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
116
|
-
return 4294967296 * (2097151 & h2) + (h1 >>> 0) || 1;
|
|
117
|
-
}
|
|
118
129
|
function modeFromStat(st) {
|
|
119
130
|
const type = st.isSymbolicLink ? S_IFLNK : st.isDirectory ? S_IFDIR : S_IFREG;
|
|
120
131
|
const fallback = st.isDirectory || st.isSymbolicLink ? 511 : 438;
|
|
@@ -242,9 +253,9 @@ function createNodeOps(h) {
|
|
|
242
253
|
gid: 0,
|
|
243
254
|
rdev: 0,
|
|
244
255
|
size,
|
|
245
|
-
atime: mtime,
|
|
256
|
+
atime: new Date(st.atimeMs ?? mtime.getTime()),
|
|
246
257
|
mtime,
|
|
247
|
-
ctime: mtime,
|
|
258
|
+
ctime: new Date(st.ctimeMs ?? mtime.getTime()),
|
|
248
259
|
blksize: 4096,
|
|
249
260
|
blocks: Math.ceil(size / 4096)
|
|
250
261
|
};
|
|
@@ -277,10 +288,13 @@ function createNodeOps(h) {
|
|
|
277
288
|
node.live.stat = void 0;
|
|
278
289
|
},
|
|
279
290
|
lookup(parent, name) {
|
|
280
|
-
const
|
|
291
|
+
const listed = parent.live.listed?.get(name);
|
|
292
|
+
parent.live.listed?.delete(name);
|
|
293
|
+
const st = listed ?? call(() => bridgeOf(parent).lstat(childPath(parent, name)));
|
|
281
294
|
return makeNode(parent, name, st);
|
|
282
295
|
},
|
|
283
296
|
mknod(parent, name, mode) {
|
|
297
|
+
parent.live.listed = void 0;
|
|
284
298
|
const path = childPath(parent, name);
|
|
285
299
|
if (Fs.isDir(mode)) {
|
|
286
300
|
call(() => bridgeOf(parent).mkdir(path));
|
|
@@ -303,6 +317,8 @@ function createNodeOps(h) {
|
|
|
303
317
|
return node;
|
|
304
318
|
},
|
|
305
319
|
rename(oldNode, newDir, newName) {
|
|
320
|
+
oldNode.parent.live.listed = void 0;
|
|
321
|
+
newDir.live.listed = void 0;
|
|
306
322
|
const from = liveNodePath(oldNode);
|
|
307
323
|
const to = childPath(newDir, newName);
|
|
308
324
|
flushNode(oldNode);
|
|
@@ -317,6 +333,7 @@ function createNodeOps(h) {
|
|
|
317
333
|
oldNode.live.stat = void 0;
|
|
318
334
|
},
|
|
319
335
|
unlink(parent, name) {
|
|
336
|
+
parent.live.listed = void 0;
|
|
320
337
|
let open;
|
|
321
338
|
try {
|
|
322
339
|
const node = Fs.lookupNode?.(parent, name);
|
|
@@ -331,19 +348,24 @@ function createNodeOps(h) {
|
|
|
331
348
|
if (open) open.live.orphan = true;
|
|
332
349
|
},
|
|
333
350
|
rmdir(parent, name) {
|
|
351
|
+
parent.live.listed = void 0;
|
|
334
352
|
call(() => bridgeOf(parent).rmdir(childPath(parent, name)));
|
|
335
353
|
},
|
|
336
354
|
readdir(node) {
|
|
337
|
-
|
|
355
|
+
const listed = call(() => bridgeOf(node).readdirStat(liveNodePath(node)));
|
|
356
|
+
node.live.listed = /* @__PURE__ */ new Map();
|
|
357
|
+
for (const [name, st] of listed) if (st) node.live.listed.set(name, st);
|
|
358
|
+
return [".", "..", ...listed.map(([name]) => name)];
|
|
338
359
|
},
|
|
339
360
|
symlink(parent, newName, target) {
|
|
361
|
+
parent.live.listed = void 0;
|
|
340
362
|
const path = childPath(parent, newName);
|
|
341
363
|
call(() => bridgeOf(parent).symlink(target, path));
|
|
342
364
|
return makeNode(parent, newName, {
|
|
343
365
|
isFile: false,
|
|
344
366
|
isDirectory: false,
|
|
345
367
|
isSymbolicLink: true,
|
|
346
|
-
size: target.length
|
|
368
|
+
size: new TextEncoder().encode(target).length
|
|
347
369
|
});
|
|
348
370
|
},
|
|
349
371
|
readlink(node) {
|
|
@@ -463,6 +485,7 @@ function invalidateLiveVfs(Fs, plugin) {
|
|
|
463
485
|
if (!ownedBy(plugin, node)) continue;
|
|
464
486
|
const s = node.live;
|
|
465
487
|
s.stat = void 0;
|
|
488
|
+
s.listed = void 0;
|
|
466
489
|
if (s.openCount === 0) {
|
|
467
490
|
if (node !== node.mount.root) drop.push(node);
|
|
468
491
|
} else if (s.loaded && !s.dirty) {
|
|
@@ -481,8 +504,8 @@ function outermostDirs(dirs) {
|
|
|
481
504
|
}
|
|
482
505
|
function describeMountError(err) {
|
|
483
506
|
if (err instanceof Error) return err.message;
|
|
484
|
-
const
|
|
485
|
-
return typeof
|
|
507
|
+
const errno2 = err?.errno;
|
|
508
|
+
return typeof errno2 === "number" ? `errno ${errno2}` : String(err);
|
|
486
509
|
}
|
|
487
510
|
function mountLiveVfsDirs(Fs, bridge, dirs, warn) {
|
|
488
511
|
if (typeof Fs.filesystems !== "object" || !Fs.filesystems) {
|
|
@@ -560,6 +583,8 @@ function parseSyncFsStat(json) {
|
|
|
560
583
|
size: s.size,
|
|
561
584
|
...typeof s.mode === "number" ? { mode: s.mode } : {},
|
|
562
585
|
...typeof s.mtimeMs === "number" ? { mtimeMs: s.mtimeMs } : {},
|
|
586
|
+
...typeof s.atimeMs === "number" ? { atimeMs: s.atimeMs } : {},
|
|
587
|
+
...typeof s.ctimeMs === "number" ? { ctimeMs: s.ctimeMs } : {},
|
|
563
588
|
...typeof s.ino === "number" ? { ino: s.ino } : {}
|
|
564
589
|
};
|
|
565
590
|
}
|
|
@@ -604,8 +629,8 @@ function decodeSabResult(status2, payload) {
|
|
|
604
629
|
case SAB_STATUS_ERRNO: {
|
|
605
630
|
try {
|
|
606
631
|
const parsed = JSON.parse(decoder.decode(payload));
|
|
607
|
-
const
|
|
608
|
-
return { ok: false, errno, message: String(parsed.message ??
|
|
632
|
+
const errno2 = typeof parsed.errno === "string" && /^E[A-Z]+$/.test(parsed.errno) ? parsed.errno : "EIO";
|
|
633
|
+
return { ok: false, errno: errno2, message: String(parsed.message ?? errno2) };
|
|
609
634
|
} catch {
|
|
610
635
|
return { ok: false, errno: "EIO", message: "sync-sab: malformed errno payload" };
|
|
611
636
|
}
|
|
@@ -781,6 +806,7 @@ var WASI_ERRNO = {
|
|
|
781
806
|
EAFNOSUPPORT: 5,
|
|
782
807
|
EAGAIN: 6,
|
|
783
808
|
ECONNREFUSED: 14,
|
|
809
|
+
EEXIST: 20,
|
|
784
810
|
EINPROGRESS: 26,
|
|
785
811
|
EISCONN: 30,
|
|
786
812
|
ENETUNREACH: 40,
|
|
@@ -818,6 +844,7 @@ var POLLHUP = 16;
|
|
|
818
844
|
var POLLRDNORM = 64;
|
|
819
845
|
var POLLWRNORM = 256;
|
|
820
846
|
var O_NONBLOCK = 2048;
|
|
847
|
+
var SOCKET_MODE = 49663;
|
|
821
848
|
var PTY_PATH = /^\/dev\/(?:ptmx|pts\/(\d+))$/;
|
|
822
849
|
function isPtyPath(path) {
|
|
823
850
|
return PTY_PATH.test(path);
|
|
@@ -865,6 +892,8 @@ function nonblocking(stream) {
|
|
|
865
892
|
}
|
|
866
893
|
var KernelStreams = class {
|
|
867
894
|
refs = /* @__PURE__ */ new Map();
|
|
895
|
+
socketRoot;
|
|
896
|
+
sockets = 0;
|
|
868
897
|
Fs;
|
|
869
898
|
sys;
|
|
870
899
|
options;
|
|
@@ -880,6 +909,27 @@ var KernelStreams = class {
|
|
|
880
909
|
if (terminal ?? this.sys.isatty?.(kfd) ?? false) stream.tty = this.ttyOps(kfd);
|
|
881
910
|
else delete stream.tty;
|
|
882
911
|
}
|
|
912
|
+
attachSocket(stream, kfd) {
|
|
913
|
+
this.attach(stream, kfd, false);
|
|
914
|
+
stream.sliccKernelSocket = true;
|
|
915
|
+
}
|
|
916
|
+
socketStream(flags) {
|
|
917
|
+
const fs = this.Fs;
|
|
918
|
+
if (!fs.mount || !fs.createNode || !fs.createStream) {
|
|
919
|
+
const stream = this.Fs.open("/dev/null", 2);
|
|
920
|
+
stream.flags = flags;
|
|
921
|
+
return stream;
|
|
922
|
+
}
|
|
923
|
+
const createNode = fs.createNode;
|
|
924
|
+
this.socketRoot ??= fs.mount({ mount: () => createNode(null, "/", 16895, 0) }, {}, null);
|
|
925
|
+
const ino = ++this.sockets;
|
|
926
|
+
const node = fs.createNode(this.socketRoot, `socket:${ino}`, SOCKET_MODE, 0);
|
|
927
|
+
const now = /* @__PURE__ */ new Date();
|
|
928
|
+
const stat = { dev: 0, ino, mode: SOCKET_MODE, nlink: 1, uid: 0, gid: 0, rdev: 0, size: 0 };
|
|
929
|
+
const times = { atime: now, mtime: now, ctime: now, blksize: 4096, blocks: 0 };
|
|
930
|
+
node.node_ops = { getattr: () => ({ ...stat, ...times }) };
|
|
931
|
+
return fs.createStream({ node, flags, seekable: false, position: 0, stream_ops: {} });
|
|
932
|
+
}
|
|
883
933
|
nameTerminal(stream) {
|
|
884
934
|
const kfd = stream.sliccKernelFd;
|
|
885
935
|
if (!stream.tty || kfd === void 0) return;
|
|
@@ -1644,6 +1694,9 @@ function describeForFork(Fs, sys, streams, livePath) {
|
|
|
1644
1694
|
}
|
|
1645
1695
|
function kernelEntry(stream, kernel) {
|
|
1646
1696
|
const cloexec = closesOnExec(stream) ? { cloexec: true } : {};
|
|
1697
|
+
if (stream.sliccKernelSocket) {
|
|
1698
|
+
return { fd: stream.fd, kernel, kind: "socket", flags: stream.flags, ...cloexec };
|
|
1699
|
+
}
|
|
1647
1700
|
const kind = stream.sliccKernelFile ? "file" : stream.tty ? "tty" : "stream";
|
|
1648
1701
|
return { fd: stream.fd, kernel, kind, ...cloexec };
|
|
1649
1702
|
}
|
|
@@ -1685,7 +1738,8 @@ function inheritedSlot(fd, stream) {
|
|
|
1685
1738
|
const access = ACCESS[stream.flags & O_ACCMODE];
|
|
1686
1739
|
return { fd, device, ...access ? { access } : {} };
|
|
1687
1740
|
}
|
|
1688
|
-
|
|
1741
|
+
const flags = stream.sliccKernelSocket ? { flags: stream.flags } : {};
|
|
1742
|
+
return { fd, kernel: stream.sliccKernelFd, ...flags };
|
|
1689
1743
|
}
|
|
1690
1744
|
function place(Fs, stream, fd) {
|
|
1691
1745
|
if (stream.fd === fd) return stream;
|
|
@@ -1693,7 +1747,8 @@ function place(Fs, stream, fd) {
|
|
|
1693
1747
|
Fs.closeStream(stream.fd);
|
|
1694
1748
|
return moved;
|
|
1695
1749
|
}
|
|
1696
|
-
function placeholder(Fs, entry) {
|
|
1750
|
+
function placeholder(Fs, streams, entry) {
|
|
1751
|
+
if (entry.kind === "socket") return streams.socketStream(entry.flags ?? O_RDWR);
|
|
1697
1752
|
if (entry.kind === "tty") return Fs.open("/dev/tty", O_RDWR);
|
|
1698
1753
|
if (entry.kind === "stream") return Fs.open("/dev/null", O_RDWR);
|
|
1699
1754
|
Fs.mkdirTree(PLACEHOLDER_DIR);
|
|
@@ -1714,8 +1769,9 @@ function asFifo(stream, streams, identity) {
|
|
|
1714
1769
|
};
|
|
1715
1770
|
}
|
|
1716
1771
|
function placeKernelStream(Fs, streams, entry) {
|
|
1717
|
-
const stream = place(Fs, placeholder(Fs, entry), entry.fd);
|
|
1772
|
+
const stream = place(Fs, placeholder(Fs, streams, entry), entry.fd);
|
|
1718
1773
|
if (entry.kind === "file") streams.attachFile(stream, entry.kernel);
|
|
1774
|
+
else if (entry.kind === "socket") streams.attachSocket(stream, entry.kernel);
|
|
1719
1775
|
else streams.attach(stream, entry.kernel, entry.kind === "tty");
|
|
1720
1776
|
if (entry.kind === "tty") streams.nameTerminal(stream);
|
|
1721
1777
|
if (entry.kind === "stream") {
|
|
@@ -1743,6 +1799,40 @@ function restoreForkedStreams(Fs, streams, table) {
|
|
|
1743
1799
|
}
|
|
1744
1800
|
}
|
|
1745
1801
|
|
|
1802
|
+
// src/process/process-http.ts
|
|
1803
|
+
var HttpError = class extends Error {
|
|
1804
|
+
code;
|
|
1805
|
+
constructor(code, message) {
|
|
1806
|
+
super(message);
|
|
1807
|
+
this.code = code;
|
|
1808
|
+
}
|
|
1809
|
+
};
|
|
1810
|
+
function createHttpKernel(transport) {
|
|
1811
|
+
const call = (req) => {
|
|
1812
|
+
const r = transport.call(req, Number.POSITIVE_INFINITY, req.op);
|
|
1813
|
+
if (!r.ok) throw new HttpError(r.errno, r.message);
|
|
1814
|
+
return r;
|
|
1815
|
+
};
|
|
1816
|
+
return {
|
|
1817
|
+
request(req) {
|
|
1818
|
+
const r = call({
|
|
1819
|
+
op: "net-request",
|
|
1820
|
+
url: req.url,
|
|
1821
|
+
method: (req.method ?? "GET").toUpperCase(),
|
|
1822
|
+
headers: req.headers ?? [],
|
|
1823
|
+
...req.body ? { body: req.body } : {}
|
|
1824
|
+
});
|
|
1825
|
+
return r.json;
|
|
1826
|
+
},
|
|
1827
|
+
read(handle, max) {
|
|
1828
|
+
return call({ op: "net-read", handle, max }).bytes;
|
|
1829
|
+
},
|
|
1830
|
+
close(handle) {
|
|
1831
|
+
call({ op: "net-close", handle });
|
|
1832
|
+
}
|
|
1833
|
+
};
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1746
1836
|
// src/process/process-signals.ts
|
|
1747
1837
|
var SignalGate = class {
|
|
1748
1838
|
reported = { caught: 0, ignored: 0 };
|
|
@@ -1805,6 +1895,160 @@ var SignalGate = class {
|
|
|
1805
1895
|
}
|
|
1806
1896
|
};
|
|
1807
1897
|
|
|
1898
|
+
// src/process/process-sockets.ts
|
|
1899
|
+
var O_RDWR2 = 2;
|
|
1900
|
+
var KILLED_BY_SIGPIPE2 = 128 + 13;
|
|
1901
|
+
function errno(e) {
|
|
1902
|
+
if (e instanceof SyscallError) return -wasiErrno(e.code);
|
|
1903
|
+
const code = e?.errno;
|
|
1904
|
+
if (typeof code === "number") return -code;
|
|
1905
|
+
throw e;
|
|
1906
|
+
}
|
|
1907
|
+
var O_WRONLY = 1;
|
|
1908
|
+
var O_CREAT3 = 64;
|
|
1909
|
+
var O_EXCL3 = 128;
|
|
1910
|
+
function resolved(Fs, addr) {
|
|
1911
|
+
if (addr.family !== "unix" || !addr.path || addr.path.startsWith("\0")) return addr;
|
|
1912
|
+
const path = addr.path.startsWith("/") ? addr.path : `${Fs.cwd()}/${addr.path}`;
|
|
1913
|
+
return { family: "unix", path: normalizePath(path) };
|
|
1914
|
+
}
|
|
1915
|
+
function socketNode(Fs, addr) {
|
|
1916
|
+
if (addr.family !== "unix" || !addr.path || addr.path.startsWith("\0")) return void 0;
|
|
1917
|
+
const fs = Fs;
|
|
1918
|
+
let stream;
|
|
1919
|
+
try {
|
|
1920
|
+
stream = Fs.open(addr.path, O_WRONLY | O_CREAT3 | O_EXCL3, 493);
|
|
1921
|
+
} catch (e) {
|
|
1922
|
+
if (e?.errno === wasiErrno("EEXIST")) {
|
|
1923
|
+
throw new SyscallError("EADDRINUSE");
|
|
1924
|
+
}
|
|
1925
|
+
throw e;
|
|
1926
|
+
}
|
|
1927
|
+
if (Fs.close) Fs.close(stream);
|
|
1928
|
+
else Fs.closeStream(stream.fd);
|
|
1929
|
+
return { remove: () => fs.unlink?.(addr.path) };
|
|
1930
|
+
}
|
|
1931
|
+
function createSocketKernel(deps) {
|
|
1932
|
+
const { transport, Fs, sys, streams } = deps;
|
|
1933
|
+
const call = (req) => {
|
|
1934
|
+
const r = transport.call(req, Number.POSITIVE_INFINITY, req.op);
|
|
1935
|
+
if (!r.ok) throw new SyscallError(r.errno);
|
|
1936
|
+
return r;
|
|
1937
|
+
};
|
|
1938
|
+
const json = (req) => {
|
|
1939
|
+
const r = call(req);
|
|
1940
|
+
return r.ok && r.kind === "json" ? r.json : void 0;
|
|
1941
|
+
};
|
|
1942
|
+
const done = (req) => {
|
|
1943
|
+
call(req);
|
|
1944
|
+
return 0;
|
|
1945
|
+
};
|
|
1946
|
+
const guard = (op) => {
|
|
1947
|
+
for (; ; ) {
|
|
1948
|
+
try {
|
|
1949
|
+
return op();
|
|
1950
|
+
} catch (e) {
|
|
1951
|
+
const restart = e instanceof SyscallError && e.code === "EINTR" && deps.restartable?.();
|
|
1952
|
+
if (!restart) return errno(e);
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
};
|
|
1956
|
+
const socketAt = (fd) => {
|
|
1957
|
+
const stream = Fs.getStream(fd);
|
|
1958
|
+
if (!stream) throw new SyscallError("EBADF");
|
|
1959
|
+
if (!stream.sliccKernelSocket || stream.sliccKernelFd === void 0) {
|
|
1960
|
+
throw new SyscallError("ENOTSOCK");
|
|
1961
|
+
}
|
|
1962
|
+
return stream;
|
|
1963
|
+
};
|
|
1964
|
+
const kfd = (fd) => socketAt(fd).sliccKernelFd;
|
|
1965
|
+
const install = (k, nonblock, cloexec = false) => {
|
|
1966
|
+
let stream;
|
|
1967
|
+
try {
|
|
1968
|
+
stream = streams.socketStream(O_RDWR2 | (nonblock ? O_NONBLOCK : 0));
|
|
1969
|
+
} catch (e) {
|
|
1970
|
+
sys.close(k);
|
|
1971
|
+
throw e;
|
|
1972
|
+
}
|
|
1973
|
+
streams.attachSocket(stream, k);
|
|
1974
|
+
setCloseOnExec(stream, cloexec);
|
|
1975
|
+
return stream.fd;
|
|
1976
|
+
};
|
|
1977
|
+
return {
|
|
1978
|
+
socket: (domain, nonblock, cloexec) => guard(() => install(json({ op: "sock-open", domain }), nonblock, cloexec)),
|
|
1979
|
+
socketpair: (domain, nonblock, cloexec) => guard(() => {
|
|
1980
|
+
const [a, b] = json({ op: "sock-pair", domain });
|
|
1981
|
+
let first;
|
|
1982
|
+
try {
|
|
1983
|
+
first = install(a, nonblock, cloexec);
|
|
1984
|
+
} catch (e) {
|
|
1985
|
+
sys.close(b);
|
|
1986
|
+
throw e;
|
|
1987
|
+
}
|
|
1988
|
+
try {
|
|
1989
|
+
return [first, install(b, nonblock, cloexec)];
|
|
1990
|
+
} catch (e) {
|
|
1991
|
+
const stream = Fs.getStream(first);
|
|
1992
|
+
if (stream) stream.stream_ops.close?.(stream);
|
|
1993
|
+
Fs.closeStream(first);
|
|
1994
|
+
throw e;
|
|
1995
|
+
}
|
|
1996
|
+
}),
|
|
1997
|
+
bind: (fd, given) => guard(() => {
|
|
1998
|
+
const addr = resolved(Fs, given);
|
|
1999
|
+
const node = socketNode(Fs, addr);
|
|
2000
|
+
try {
|
|
2001
|
+
return done({ op: "sock-bind", fd: kfd(fd), addr });
|
|
2002
|
+
} catch (e) {
|
|
2003
|
+
node?.remove();
|
|
2004
|
+
throw e;
|
|
2005
|
+
}
|
|
2006
|
+
}),
|
|
2007
|
+
listen: (fd, backlog) => guard(() => done({ op: "sock-listen", fd: kfd(fd), backlog })),
|
|
2008
|
+
accept: (fd, nonblock, cloexec) => guard(() => {
|
|
2009
|
+
const listener = socketAt(fd);
|
|
2010
|
+
const req = {
|
|
2011
|
+
op: "sock-accept",
|
|
2012
|
+
fd: listener.sliccKernelFd,
|
|
2013
|
+
nonblock: (listener.flags & O_NONBLOCK) !== 0
|
|
2014
|
+
};
|
|
2015
|
+
const got = json(req);
|
|
2016
|
+
return { fd: install(got.fd, nonblock, cloexec), peer: got.peer };
|
|
2017
|
+
}),
|
|
2018
|
+
connect: (fd, addr) => guard(() => {
|
|
2019
|
+
const stream = socketAt(fd);
|
|
2020
|
+
const nonblock = (stream.flags & O_NONBLOCK) !== 0;
|
|
2021
|
+
return done({
|
|
2022
|
+
op: "sock-connect",
|
|
2023
|
+
fd: stream.sliccKernelFd,
|
|
2024
|
+
addr: resolved(Fs, addr),
|
|
2025
|
+
nonblock
|
|
2026
|
+
});
|
|
2027
|
+
}),
|
|
2028
|
+
shutdown: (fd, how) => guard(() => done({ op: "sock-shutdown", fd: kfd(fd), how })),
|
|
2029
|
+
name: (fd, peer) => guard(() => json({ op: "sock-name", fd: kfd(fd), peer })),
|
|
2030
|
+
getopt: (fd, level, name) => guard(() => ({ value: json({ op: "sock-getopt", fd: kfd(fd), level, name }) })),
|
|
2031
|
+
setopt: (fd, level, name, value) => guard(() => done({ op: "sock-setopt", fd: kfd(fd), level, name, value })),
|
|
2032
|
+
send: (fd, bytes, flags) => guard(() => {
|
|
2033
|
+
const stream = socketAt(fd);
|
|
2034
|
+
const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
|
|
2035
|
+
try {
|
|
2036
|
+
return sys.write(stream.sliccKernelFd, bytes, { nonblock });
|
|
2037
|
+
} catch (e) {
|
|
2038
|
+
const broken = e instanceof SyscallError && e.code === "EPIPE";
|
|
2039
|
+
if (broken && !flags.nosignal && !deps.sigpipe?.())
|
|
2040
|
+
throw new ProcessExit(KILLED_BY_SIGPIPE2);
|
|
2041
|
+
throw e;
|
|
2042
|
+
}
|
|
2043
|
+
}),
|
|
2044
|
+
recv: (fd, max, flags) => guard(() => {
|
|
2045
|
+
const stream = socketAt(fd);
|
|
2046
|
+
const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
|
|
2047
|
+
return sys.read(stream.sliccKernelFd, max, { nonblock, peek: flags.peek === true });
|
|
2048
|
+
})
|
|
2049
|
+
};
|
|
2050
|
+
}
|
|
2051
|
+
|
|
1808
2052
|
// src/process/realm-user.ts
|
|
1809
2053
|
var REALM_UID = 1e3;
|
|
1810
2054
|
var REALM_GID = 1e3;
|
|
@@ -1934,10 +2178,10 @@ function wireKernelFd(Fs, streams, entry) {
|
|
|
1934
2178
|
});
|
|
1935
2179
|
}
|
|
1936
2180
|
var O_RDONLY = 0;
|
|
1937
|
-
var
|
|
1938
|
-
var
|
|
2181
|
+
var O_WRONLY2 = 1;
|
|
2182
|
+
var O_RDWR3 = 2;
|
|
1939
2183
|
function openDevice(Fs, fd, meta) {
|
|
1940
|
-
const flags = meta.access === "read" ? O_RDONLY : meta.access === "write" ?
|
|
2184
|
+
const flags = meta.access === "read" ? O_RDONLY : meta.access === "write" ? O_WRONLY2 : O_RDWR3;
|
|
1941
2185
|
let stream;
|
|
1942
2186
|
try {
|
|
1943
2187
|
stream = Fs.open(`/dev/${meta.device}`, flags);
|
|
@@ -2131,6 +2375,15 @@ async function runWasmProcess(init, port, deps = {}) {
|
|
|
2131
2375
|
inherit: (actions) => describeInherited(running.FS, sys, streams, livePath, actions),
|
|
2132
2376
|
stdioPromoter: () => vfsPromoter(running.FS, sys, streams, livePath)
|
|
2133
2377
|
});
|
|
2378
|
+
running.sliccKernel.http = createHttpKernel(transport);
|
|
2379
|
+
running.sliccKernel.net = createSocketKernel({
|
|
2380
|
+
transport,
|
|
2381
|
+
Fs: running.FS,
|
|
2382
|
+
sys,
|
|
2383
|
+
streams,
|
|
2384
|
+
sigpipe,
|
|
2385
|
+
restartable
|
|
2386
|
+
});
|
|
2134
2387
|
try {
|
|
2135
2388
|
return runMain(running, init);
|
|
2136
2389
|
} finally {
|