@ai-ecoverse/slicc-kernel 1.10.0 → 1.11.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
CHANGED
|
@@ -183,6 +183,8 @@ Directories are renamed with `FileSystemHandle.move()` where available, else by
|
|
|
183
183
|
|
|
184
184
|
Every process of the kernel has `/proc/<pid>/` with `cmdline`, `comm`, `stat`, `statm` and `status`, in the formats procps reads, and `/proc/self/` has the same files for the process that reads them. They come from the kernel's process table when they are opened, so a terminal sees the processes of every client; an exec'd program shows under the pid its parent knows. `/proc/uptime`, `/proc/loadavg`, `/proc/stat` and `/proc/meminfo` are there too, and `/proc/mounts`. Pids, parents, process groups, sessions, command lines, terminals, start and boot times are real; CPU times, memory sizes, load and `MemTotal` (from `navigator.deviceMemory`, else 4 GiB) are placeholders. Only Emscripten processes see this `/proc`.
|
|
185
185
|
|
|
186
|
+
While OPFS has no `/etc/passwd`, `/etc/group` or `/etc/mtab`, reading them gets per-process ones: root is uid 0 and the realm user, uid 1000, is named after `USER`, or `web_user` (Emscripten's default) without one, so it matches `$USER`, with `HOME` as its home, so `id`, `whoami`, `ls -l` and `ps` show names. Nothing is written to OPFS, and a real file there wins.
|
|
187
|
+
|
|
186
188
|
### Metadata
|
|
187
189
|
|
|
188
190
|
OPFS stores names, bytes, sizes and modification times, nothing else. Everything POSIX needs on top of that lives in an IndexedDB sidecar, so it survives reloads and new kernels:
|
|
@@ -1916,28 +1916,50 @@ function mountTable() {
|
|
|
1916
1916
|
"\n"
|
|
1917
1917
|
);
|
|
1918
1918
|
}
|
|
1919
|
-
function
|
|
1920
|
-
const
|
|
1919
|
+
function accounts(env = {}) {
|
|
1920
|
+
const user = env.USER ?? "web_user";
|
|
1921
|
+
const name = NAME.test(user) && user !== "root" ? user : "user";
|
|
1922
|
+
const home = env.HOME || "/home";
|
|
1923
|
+
return {
|
|
1924
|
+
passwd: `root:x:0:0:root:/root:/bin/sh
|
|
1925
|
+
${name}:x:1000:1000:${name}:${home}:/bin/bash
|
|
1926
|
+
`,
|
|
1927
|
+
group: `root:x:0:
|
|
1928
|
+
${name}:x:1000:
|
|
1929
|
+
`
|
|
1930
|
+
};
|
|
1931
|
+
}
|
|
1932
|
+
function useMounts(Fs, env = {}) {
|
|
1933
|
+
const { writeFile, mkdirTree } = Fs;
|
|
1921
1934
|
if (typeof Fs.open !== "function" || typeof writeFile !== "function") return;
|
|
1935
|
+
const { passwd, group } = accounts(env);
|
|
1936
|
+
const backing = { "/etc/mtab": "/proc/mounts" };
|
|
1922
1937
|
try {
|
|
1923
1938
|
writeFile.call(Fs, "/proc/mounts", mountTable());
|
|
1924
1939
|
} catch {
|
|
1925
1940
|
return;
|
|
1926
1941
|
}
|
|
1942
|
+
try {
|
|
1943
|
+
mkdirTree.call(Fs, "/dev/.etc");
|
|
1944
|
+
writeFile.call(Fs, "/dev/.etc/passwd", passwd);
|
|
1945
|
+
writeFile.call(Fs, "/dev/.etc/group", group);
|
|
1946
|
+
backing["/etc/passwd"] = "/dev/.etc/passwd";
|
|
1947
|
+
backing["/etc/group"] = "/dev/.etc/group";
|
|
1948
|
+
} catch {
|
|
1949
|
+
}
|
|
1927
1950
|
const open = Fs.open.bind(Fs);
|
|
1928
1951
|
Fs.open = (path, flags, mode) => {
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
}
|
|
1952
|
+
const instead = backing[path];
|
|
1953
|
+
if (!instead || (flags & (O_ACCMODE | O_CREAT2)) !== 0) return open(path, flags, mode);
|
|
1932
1954
|
try {
|
|
1933
1955
|
return open(path, flags, mode);
|
|
1934
1956
|
} catch (e) {
|
|
1935
1957
|
if (e?.errno !== wasiErrno("ENOENT")) throw e;
|
|
1936
|
-
return open(
|
|
1958
|
+
return open(instead, flags, mode);
|
|
1937
1959
|
}
|
|
1938
1960
|
};
|
|
1939
1961
|
}
|
|
1940
|
-
var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, DIR_MODE, LINK_MODE, O_ACCMODE, O_CREAT2;
|
|
1962
|
+
var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, DIR_MODE, LINK_MODE, O_ACCMODE, O_CREAT2, NAME;
|
|
1941
1963
|
var init_process_fds = __esm({
|
|
1942
1964
|
"src/process/process-fds.ts"() {
|
|
1943
1965
|
"use strict";
|
|
@@ -1965,6 +1987,7 @@ var init_process_fds = __esm({
|
|
|
1965
1987
|
LINK_MODE = 41408;
|
|
1966
1988
|
O_ACCMODE = 3;
|
|
1967
1989
|
O_CREAT2 = 64;
|
|
1990
|
+
NAME = /^[a-z_][a-z0-9_-]*$/i;
|
|
1968
1991
|
}
|
|
1969
1992
|
});
|
|
1970
1993
|
|
|
@@ -2960,6 +2983,8 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
2960
2983
|
const restartable = () => signals.restartable();
|
|
2961
2984
|
const streams = new KernelStreams(running.FS, sys, { sigpipe, restartable });
|
|
2962
2985
|
trackCloseOnExec(running.FS);
|
|
2986
|
+
useMounts(running.FS, init.env);
|
|
2987
|
+
useProcfs(running.FS, sys, init.pid);
|
|
2963
2988
|
if (init.fork) restoreForkedStreams(running.FS, streams, init.fork.streams ?? []);
|
|
2964
2989
|
else {
|
|
2965
2990
|
wireKernelStdio(running.FS, streams);
|
|
@@ -2969,8 +2994,6 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
2969
2994
|
if (pipefs) streams.usePipes(pipefs);
|
|
2970
2995
|
streams.useControllingTerminal();
|
|
2971
2996
|
useDevFd(running.FS);
|
|
2972
|
-
useMounts(running.FS);
|
|
2973
|
-
useProcfs(running.FS, sys, init.pid);
|
|
2974
2997
|
ownByRealmUser(running.FS);
|
|
2975
2998
|
const livePath = (s) => liveNodePath(s.node);
|
|
2976
2999
|
running.sliccKernel = createProcessKernel({
|