@ai-ecoverse/slicc-kernel 1.34.1 → 1.35.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 +16 -0
- package/dist/kernel-worker.js +122 -35
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +158 -8
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +122 -35
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +158 -8
- package/dist/process-worker.js.map +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -421,6 +421,22 @@ An exec'd program takes over the pid of the process it replaces, as on Linux: `g
|
|
|
421
421
|
- **Emscripten:** `Module.sliccKernel.execve(file, argv, env, cwd)` runs `file` as this process's new image on its fds 0, 1 and 2, waits for it, and returns its wait status, or a negative errno when it cannot start. `env` and `cwd` may be `null` for this process's own. An exec shim detects it with `typeof Module.sliccKernel.execve === 'function'` and exits with the status it returns, as `execve` never returns on success. Older shims spawn the program and then call `Module.sliccKernel.execWait(pid)`; that works the same way: a new program asks the kernel for its pid before `main`, and the kernel answers once its parent has made its next call, so an image an older shim execs also reports the pid it replaced (the wait starts once the program is loaded; should the parent make no call within 100 ms after that, the kernel answers anyway, and the image may then report its own pid; `launcher.identities` counts the programs that asked and those answered by that timeout).
|
|
422
422
|
- **WASIX:** `proc_exec` does this by itself.
|
|
423
423
|
|
|
424
|
+
### File modes and the umask
|
|
425
|
+
|
|
426
|
+
Every process has a umask in the kernel, `022` for a process the embedder starts, inherited across fork, spawn and exec and shown in `/proc/<pid>/status` (`Umask:`). The kernel applies it when a program creates a file or directory, whatever its libc does: an Emscripten program's `open` with `O_CREAT`, `mkdir` and `mknod` (so `umask 077; touch f` gives `600` in a child too), and a WASI program's `path_open` with `O_CREAT` and `path_create_directory` (`0666` and `0777` less the umask).
|
|
427
|
+
|
|
428
|
+
WASI and WASIX have no call for file modes, so the kernel adds the import module `slicc_fs`, whose functions return a preview1 errno (kernels without them answer `ENOSYS`):
|
|
429
|
+
|
|
430
|
+
| Import | Does |
|
|
431
|
+
| --- | --- |
|
|
432
|
+
| `fd_chmod(fd, mode)` | `fchmod` on an open file or directory |
|
|
433
|
+
| `path_chmod(dirfd, path, path_len, mode, flags)` | `fchmodat`; with `flags & 1` (`AT_SYMLINK_NOFOLLOW`) a symlink answers `ENOTSUP` and is never followed |
|
|
434
|
+
| `umask(mask, old_out)` | sets the process's umask and writes the previous one |
|
|
435
|
+
| `fd_mode(fd, mode_out)` | the permission bits of an open file or directory |
|
|
436
|
+
| `path_mode(dirfd, path, path_len, flags, mode_out)` | those of a path, of the link itself with `flags & 1` |
|
|
437
|
+
|
|
438
|
+
Lowering a soft resource limit (`ulimit -S -n 64`) still fails with `EPERM` in Emscripten programs: their libc's `setrlimit` is a stub compiled into the program, not a call to the kernel.
|
|
439
|
+
|
|
424
440
|
### `/proc`
|
|
425
441
|
|
|
426
442
|
Every process of the kernel has `/proc/<pid>/` with `cmdline`, `comm`, `stat`, `statm` and `status`, in the formats procps reads, and `/proc/self` is a link to the `/proc/<pid>` of the process that reads it, as on Linux (`readlink /proc/self` is its pid, the one it was exec'd under included). 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`. A process with no parent in the kernel (one a page, a client or the Node entry started) has parent 1, as children of init do, in `getppid()`, `/proc/<pid>/stat` and `ps` alike, and so does a process whose parent has ended, waited for or not (`getppid()` asks the kernel each time; a shell's `$PPID` keeps the value it started with, as on Linux). Pids, parents, process groups, sessions, command lines, terminals, start and boot times are real, and so is each process's memory: the size of its wasm memory (`VSZ` and `RSS` alike, as wasm has no paging), which `/proc/meminfo` counts as used. CPU times, load and `MemTotal` (from `navigator.deviceMemory`, else 4 GiB) are placeholders. Only Emscripten processes see this `/proc`.
|
package/dist/kernel-worker.js
CHANGED
|
@@ -755,6 +755,9 @@ var OpfsFs = class {
|
|
|
755
755
|
ctimeMs: now
|
|
756
756
|
}));
|
|
757
757
|
}
|
|
758
|
+
async realpath(path, follow) {
|
|
759
|
+
return (await this.locate(path, follow)).path;
|
|
760
|
+
}
|
|
758
761
|
async readlink(path) {
|
|
759
762
|
const found = await this.locate(path, false);
|
|
760
763
|
if (found.link) return found.link.link;
|
|
@@ -4787,6 +4790,7 @@ function withCommandDirs(fs, names) {
|
|
|
4787
4790
|
rename: (from, to) => fs.rename(from, to),
|
|
4788
4791
|
symlink: (target, path) => fs.symlink(target, path),
|
|
4789
4792
|
readlink: (path) => fs.readlink(path),
|
|
4793
|
+
...fs.realpath ? { realpath: fs.realpath.bind(fs) } : {},
|
|
4790
4794
|
chmod: (path, mode) => fs.chmod(path, mode),
|
|
4791
4795
|
utimes: (path, atime, mtime) => fs.utimes(path, atime, mtime),
|
|
4792
4796
|
lutimes: (path, atime, mtime) => lutimesOf(fs, path, atime, mtime),
|
|
@@ -5784,6 +5788,12 @@ var MountFs = class {
|
|
|
5784
5788
|
this.table.forget(found.mount, normalizePath(path));
|
|
5785
5789
|
await found.mount.conn.call({ op: "symlink", target, path: found.rel });
|
|
5786
5790
|
}
|
|
5791
|
+
async realpath(path, follow) {
|
|
5792
|
+
if (this.at(path) || !this.base.realpath) throw errnoError("ENOSYS", path);
|
|
5793
|
+
const real = await this.base.realpath(path, follow);
|
|
5794
|
+
if (this.at(real)) throw errnoError("ENOSYS", path);
|
|
5795
|
+
return real;
|
|
5796
|
+
}
|
|
5787
5797
|
async readlink(path) {
|
|
5788
5798
|
const found = this.at(path);
|
|
5789
5799
|
if (!found) return this.base.readlink(path);
|
|
@@ -7556,9 +7566,21 @@ var VfsNodes = class {
|
|
|
7556
7566
|
}
|
|
7557
7567
|
async entryKey(path) {
|
|
7558
7568
|
const parent = parentOf5(path);
|
|
7559
|
-
const dir = await
|
|
7560
|
-
|
|
7561
|
-
|
|
7569
|
+
const dir = await this.real(parent, true, () => realDir(this.fs, parent));
|
|
7570
|
+
return joinName(dir, path.slice(path.lastIndexOf("/") + 1));
|
|
7571
|
+
}
|
|
7572
|
+
targetKey(path) {
|
|
7573
|
+
return this.real(path, true, () => realTarget(this.fs, path));
|
|
7574
|
+
}
|
|
7575
|
+
async real(path, follow, walk) {
|
|
7576
|
+
if (this.fs.realpath) {
|
|
7577
|
+
try {
|
|
7578
|
+
return await this.fs.realpath(path, follow);
|
|
7579
|
+
} catch (err) {
|
|
7580
|
+
if (errCode(err) === "ELOOP") throw err;
|
|
7581
|
+
}
|
|
7582
|
+
}
|
|
7583
|
+
return walk();
|
|
7562
7584
|
}
|
|
7563
7585
|
createExclusive(path) {
|
|
7564
7586
|
return this.onEntry(path, async () => {
|
|
@@ -7653,10 +7675,9 @@ function parentOf5(path) {
|
|
|
7653
7675
|
async function linkOf(fs, path) {
|
|
7654
7676
|
return fs.readlink?.(path).catch(() => void 0);
|
|
7655
7677
|
}
|
|
7656
|
-
async function realDir(fs, dir) {
|
|
7678
|
+
async function realDir(fs, dir, budget = { hops: 0 }) {
|
|
7657
7679
|
const queue = dir.split("/").filter(Boolean);
|
|
7658
7680
|
let at = "/";
|
|
7659
|
-
let hops = 0;
|
|
7660
7681
|
while (queue.length > 0) {
|
|
7661
7682
|
const part = queue.shift();
|
|
7662
7683
|
if (part === ".") continue;
|
|
@@ -7665,28 +7686,41 @@ async function realDir(fs, dir) {
|
|
|
7665
7686
|
continue;
|
|
7666
7687
|
}
|
|
7667
7688
|
const next = at === "/" ? `/${part}` : `${at}/${part}`;
|
|
7668
|
-
const link2 =
|
|
7689
|
+
const link2 = await linkOf(fs, next);
|
|
7669
7690
|
if (link2 === void 0) {
|
|
7670
7691
|
at = next;
|
|
7671
7692
|
continue;
|
|
7672
7693
|
}
|
|
7673
|
-
hops
|
|
7694
|
+
if (budget.hops >= MAX_LINKS5) throw fsError("ELOOP", dir);
|
|
7695
|
+
budget.hops++;
|
|
7674
7696
|
queue.unshift(...link2.split("/").filter(Boolean));
|
|
7675
7697
|
if (link2.startsWith("/")) at = "/";
|
|
7676
7698
|
}
|
|
7677
7699
|
return at;
|
|
7678
7700
|
}
|
|
7679
|
-
|
|
7680
|
-
|
|
7701
|
+
function errCode(err) {
|
|
7702
|
+
return err?.code;
|
|
7703
|
+
}
|
|
7704
|
+
function joinName(dir, name2) {
|
|
7705
|
+
return dir === "/" ? `/${name2}` : `${dir}/${name2}`;
|
|
7706
|
+
}
|
|
7707
|
+
async function realTarget(fs, path) {
|
|
7708
|
+
const budget = { hops: 0 };
|
|
7709
|
+
let dir = await realDir(fs, parentOf5(path), budget);
|
|
7681
7710
|
let name2 = path.slice(path.lastIndexOf("/") + 1);
|
|
7682
|
-
for (
|
|
7683
|
-
const link2 = await linkOf(fs, dir
|
|
7684
|
-
if (link2 === void 0)
|
|
7685
|
-
|
|
7686
|
-
|
|
7711
|
+
for (; ; ) {
|
|
7712
|
+
const link2 = await linkOf(fs, joinName(dir, name2));
|
|
7713
|
+
if (link2 === void 0) break;
|
|
7714
|
+
if (budget.hops >= MAX_LINKS5) throw fsError("ELOOP", path);
|
|
7715
|
+
budget.hops++;
|
|
7716
|
+
const target = link2.startsWith("/") ? link2 : joinName(dir, link2);
|
|
7717
|
+
dir = await realDir(fs, parentOf5(target), budget);
|
|
7687
7718
|
name2 = target.slice(target.lastIndexOf("/") + 1);
|
|
7688
7719
|
}
|
|
7689
|
-
return dir;
|
|
7720
|
+
return joinName(dir, name2);
|
|
7721
|
+
}
|
|
7722
|
+
async function targetDir(fs, path) {
|
|
7723
|
+
return parentOf5(await realTarget(fs, path).catch(() => path));
|
|
7690
7724
|
}
|
|
7691
7725
|
async function refuseReadonly(fs, path, flags, opts = {}) {
|
|
7692
7726
|
const writes = (flags & O_ACCMODE) !== 0 || opts.truncate === true;
|
|
@@ -7705,13 +7739,14 @@ function keepingOpen(fs, nodes) {
|
|
|
7705
7739
|
return {
|
|
7706
7740
|
...fs,
|
|
7707
7741
|
async rm(path, options) {
|
|
7708
|
-
const at = fs.resolvePath("/", path);
|
|
7742
|
+
const at = await nodes.entryKey(fs.resolvePath("/", path));
|
|
7709
7743
|
await nodes.unlinking(at);
|
|
7710
7744
|
await fs.rm(path, options);
|
|
7711
7745
|
nodes.unlinked(at);
|
|
7712
7746
|
},
|
|
7713
|
-
rename(from, to) {
|
|
7714
|
-
const
|
|
7747
|
+
async rename(from, to) {
|
|
7748
|
+
const a = await nodes.entryKey(fs.resolvePath("/", from));
|
|
7749
|
+
const b = await nodes.entryKey(fs.resolvePath("/", to));
|
|
7715
7750
|
return nodes.onEntry(b, async () => {
|
|
7716
7751
|
await nodes.unlinking(b);
|
|
7717
7752
|
await fs.rename(from, to);
|
|
@@ -7857,10 +7892,12 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
7857
7892
|
"fd-cloexec",
|
|
7858
7893
|
"fd-list",
|
|
7859
7894
|
"proc-alarm",
|
|
7895
|
+
"proc-umask",
|
|
7860
7896
|
"dl-log",
|
|
7861
7897
|
"fd-renumber",
|
|
7862
7898
|
"fd-promote",
|
|
7863
7899
|
"fd-open-tty",
|
|
7900
|
+
"fd-tty-names",
|
|
7864
7901
|
"tty-get",
|
|
7865
7902
|
"tty-set",
|
|
7866
7903
|
"tty-winsz",
|
|
@@ -7894,6 +7931,7 @@ function isWasmSyscall(req) {
|
|
|
7894
7931
|
return typeof op === "string" && SYSCALL_OPS.has(op);
|
|
7895
7932
|
}
|
|
7896
7933
|
var MAX_READ = 1024 * 1024;
|
|
7934
|
+
var DEFAULT_UMASK = 18;
|
|
7897
7935
|
var DYING = { ok: false, errno: "EINTR", message: "the process is being killed" };
|
|
7898
7936
|
var HOSTS_ONLY = new Resolver({ routes: new Routes() });
|
|
7899
7937
|
var WasmProcess = class {
|
|
@@ -7904,6 +7942,7 @@ var WasmProcess = class {
|
|
|
7904
7942
|
inherited = 0;
|
|
7905
7943
|
interrupt = new AbortController();
|
|
7906
7944
|
dying = false;
|
|
7945
|
+
umask = DEFAULT_UMASK;
|
|
7907
7946
|
execChild;
|
|
7908
7947
|
execTermsig;
|
|
7909
7948
|
stopped = 0;
|
|
@@ -7921,6 +7960,7 @@ var WasmProcess = class {
|
|
|
7921
7960
|
this.fds = fds;
|
|
7922
7961
|
this.options = options;
|
|
7923
7962
|
this.inherited = options.ignored ?? 0;
|
|
7963
|
+
this.umask = options.umask ?? DEFAULT_UMASK;
|
|
7924
7964
|
this.children = new ChildTable(fds, options.spawner, options.forker);
|
|
7925
7965
|
this.nodes = options.nodes ?? new VfsNodes(options.fs);
|
|
7926
7966
|
if (!options.nodes) options.openFiles?.add(this.nodes);
|
|
@@ -7993,6 +8033,11 @@ var WasmProcess = class {
|
|
|
7993
8033
|
return result;
|
|
7994
8034
|
}
|
|
7995
8035
|
}
|
|
8036
|
+
setUmask(mask) {
|
|
8037
|
+
const old = this.umask;
|
|
8038
|
+
if (mask !== void 0) this.umask = mask & 511;
|
|
8039
|
+
return old;
|
|
8040
|
+
}
|
|
7996
8041
|
die() {
|
|
7997
8042
|
if (this.dying) return;
|
|
7998
8043
|
this.dying = true;
|
|
@@ -8063,9 +8108,21 @@ var WasmProcess = class {
|
|
|
8063
8108
|
await refuseReadonly(this.options.fs, req.path, req.flags, req);
|
|
8064
8109
|
const fd = this.fds.install(heldFile(), 3);
|
|
8065
8110
|
try {
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8111
|
+
const nodes = this.nodes;
|
|
8112
|
+
const path = req.orphan ? req.path : req.exclusive ? await nodes.entryKey(req.path) : await nodes.targetKey(req.path);
|
|
8113
|
+
const open = { ...req, path };
|
|
8114
|
+
if (req.exclusive) {
|
|
8115
|
+
await nodes.createExclusive(path);
|
|
8116
|
+
this.fds.installAt(fd, this.openVfsFile(open));
|
|
8117
|
+
} else if (req.create) {
|
|
8118
|
+
await nodes.onEntry(path, async () => {
|
|
8119
|
+
this.fds.installAt(fd, this.openVfsFile(open));
|
|
8120
|
+
await this.fds.get(fd).file.stat?.();
|
|
8121
|
+
});
|
|
8122
|
+
} else {
|
|
8123
|
+
this.fds.installAt(fd, this.openVfsFile(open));
|
|
8124
|
+
}
|
|
8125
|
+
if (req.existing && !await present(this.options.fs, path, true)) {
|
|
8069
8126
|
throw new KernelError("ENOENT");
|
|
8070
8127
|
}
|
|
8071
8128
|
} catch (err) {
|
|
@@ -8144,7 +8201,7 @@ var WasmProcess = class {
|
|
|
8144
8201
|
case "fd-reserve":
|
|
8145
8202
|
return { ok: true, kind: "json", json: this.reserve(req.fd, req.min, req.meta) };
|
|
8146
8203
|
case "fd-promote":
|
|
8147
|
-
this.promote(req);
|
|
8204
|
+
await this.promote(req);
|
|
8148
8205
|
return { ok: true, kind: "void" };
|
|
8149
8206
|
case "fd-renumber":
|
|
8150
8207
|
if (req.from !== req.to) {
|
|
@@ -8157,6 +8214,8 @@ var WasmProcess = class {
|
|
|
8157
8214
|
if (!tty) throw new KernelError("ENXIO");
|
|
8158
8215
|
return { ok: true, kind: "json", json: this.fds.install(tty.file(), 3) };
|
|
8159
8216
|
}
|
|
8217
|
+
case "fd-tty-names":
|
|
8218
|
+
return { ok: true, kind: "json", json: this.options.jobs?.terminalNames() ?? [] };
|
|
8160
8219
|
case "fd-select": {
|
|
8161
8220
|
const { read, write, timeoutMs } = req;
|
|
8162
8221
|
const signal = this.blockingSignal();
|
|
@@ -8178,10 +8237,14 @@ var WasmProcess = class {
|
|
|
8178
8237
|
async vfsSyscall(req) {
|
|
8179
8238
|
if ("path" in req || "from" in req) {
|
|
8180
8239
|
const nodes = this.nodes;
|
|
8181
|
-
if (req.op === "fd-path-flush")
|
|
8182
|
-
|
|
8183
|
-
else if (req.op === "fd-path-
|
|
8184
|
-
|
|
8240
|
+
if (req.op === "fd-path-flush") {
|
|
8241
|
+
await nodes.flush(await nodes.targetKey(req.path).catch(() => req.path));
|
|
8242
|
+
} else if (req.op === "fd-path-unlinking")
|
|
8243
|
+
await nodes.unlinking(await nodes.entryKey(req.path));
|
|
8244
|
+
else if (req.op === "fd-path-unlinked") nodes.unlinked(await nodes.entryKey(req.path));
|
|
8245
|
+
else if (req.op === "fd-path-renamed") {
|
|
8246
|
+
nodes.renamed(await nodes.entryKey(req.from), await nodes.entryKey(req.to));
|
|
8247
|
+
}
|
|
8185
8248
|
return { ok: true, kind: "void" };
|
|
8186
8249
|
}
|
|
8187
8250
|
const file = this.fds.get(req.fd).file;
|
|
@@ -8202,17 +8265,19 @@ var WasmProcess = class {
|
|
|
8202
8265
|
return { ok: true, kind: "json", json: await file.stat() };
|
|
8203
8266
|
}
|
|
8204
8267
|
}
|
|
8205
|
-
promote(req) {
|
|
8268
|
+
async promote(req) {
|
|
8206
8269
|
if (!this.fds.get(req.fd).file.held) throw new KernelError("EBADF");
|
|
8207
8270
|
if (req.share !== void 0) {
|
|
8208
8271
|
this.fds.dup2(req.share, req.fd);
|
|
8209
8272
|
return;
|
|
8210
8273
|
}
|
|
8211
8274
|
if (req.path === void 0) throw new KernelError("EINVAL");
|
|
8275
|
+
const path = req.orphan ? req.path : await this.nodes.targetKey(req.path);
|
|
8276
|
+
if (!this.fds.get(req.fd).file.held) throw new KernelError("EBADF");
|
|
8212
8277
|
const file = vfsFile(
|
|
8213
8278
|
this.options.fs,
|
|
8214
8279
|
{
|
|
8215
|
-
path
|
|
8280
|
+
path,
|
|
8216
8281
|
flags: req.flags ?? 0,
|
|
8217
8282
|
position: req.position ?? 0,
|
|
8218
8283
|
...req.contents !== void 0 ? { contents: req.contents } : {},
|
|
@@ -8388,6 +8453,8 @@ var WasmProcess = class {
|
|
|
8388
8453
|
case "proc-alarm":
|
|
8389
8454
|
this.setAlarm(req.sig, req.firstMs ?? req.ms, req.repeat ? req.ms : 0, req.timer);
|
|
8390
8455
|
return { ok: true, kind: "void" };
|
|
8456
|
+
case "proc-umask":
|
|
8457
|
+
return { ok: true, kind: "json", json: this.setUmask(req.mask) };
|
|
8391
8458
|
case "dl-log":
|
|
8392
8459
|
if (req.append) this.dlLog.push(req.append);
|
|
8393
8460
|
return { ok: true, kind: "json", json: this.dlLog.slice(req.from) };
|
|
@@ -8537,7 +8604,7 @@ var Dying = class {
|
|
|
8537
8604
|
return [typeof reported === "number" ? reported : CRASHED, void 0];
|
|
8538
8605
|
}
|
|
8539
8606
|
};
|
|
8540
|
-
function processInit(opts, sab) {
|
|
8607
|
+
function processInit(opts, sab, umask) {
|
|
8541
8608
|
const base = {
|
|
8542
8609
|
type: WASM_PROCESS_INIT,
|
|
8543
8610
|
pid: opts.shownPid ?? opts.pid,
|
|
@@ -8546,6 +8613,7 @@ function processInit(opts, sab) {
|
|
|
8546
8613
|
env: opts.env,
|
|
8547
8614
|
cwd: opts.cwd,
|
|
8548
8615
|
sab,
|
|
8616
|
+
umask,
|
|
8549
8617
|
...opts.ppid !== void 0 ? { ppid: opts.ppid } : {}
|
|
8550
8618
|
};
|
|
8551
8619
|
if (opts.program.abi === "js") {
|
|
@@ -8557,11 +8625,17 @@ function processInit(opts, sab) {
|
|
|
8557
8625
|
...opts.fork ? { fork: opts.fork } : { fds: inheritedFds(opts.fds) }
|
|
8558
8626
|
};
|
|
8559
8627
|
}
|
|
8628
|
+
function inherited(opts) {
|
|
8629
|
+
return {
|
|
8630
|
+
...opts.ignored ? { ignored: opts.ignored } : {},
|
|
8631
|
+
...opts.umask !== void 0 ? { umask: opts.umask } : {}
|
|
8632
|
+
};
|
|
8633
|
+
}
|
|
8560
8634
|
function spawnWasmProcess(opts) {
|
|
8561
8635
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
8562
8636
|
const header2 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
8563
8637
|
const process = new WasmProcess(opts.pid, opts.fds, {
|
|
8564
|
-
...opts
|
|
8638
|
+
...inherited(opts),
|
|
8565
8639
|
...opts.identity ? { identity: opts.identity } : {},
|
|
8566
8640
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
8567
8641
|
spawner: opts.spawner,
|
|
@@ -8695,7 +8769,7 @@ function spawnWasmProcess(opts) {
|
|
|
8695
8769
|
};
|
|
8696
8770
|
tw.postMessage(tinit);
|
|
8697
8771
|
};
|
|
8698
|
-
const init = processInit(opts, sab);
|
|
8772
|
+
const init = processInit(opts, sab, process.umask);
|
|
8699
8773
|
worker.postMessage(init, opts.fork ? [opts.fork.memory.buffer] : []);
|
|
8700
8774
|
const signal = (sig) => {
|
|
8701
8775
|
if (process.signal(sig) !== "terminate") return;
|
|
@@ -8713,6 +8787,7 @@ function spawnWasmProcess(opts) {
|
|
|
8713
8787
|
onState: (listener) => process.onState(listener),
|
|
8714
8788
|
memory: () => Atomics.load(header2, SAB_I_MEMORY) * 65536,
|
|
8715
8789
|
ignoredSignals: (fork) => process.inheritable(fork),
|
|
8790
|
+
umask: () => process.umask,
|
|
8716
8791
|
writesBack: () => opts.program.abi === "wasi" && !done4
|
|
8717
8792
|
};
|
|
8718
8793
|
}
|
|
@@ -8818,8 +8893,13 @@ var JobTable = class {
|
|
|
8818
8893
|
return id;
|
|
8819
8894
|
}
|
|
8820
8895
|
terminalNamed(name2) {
|
|
8821
|
-
|
|
8822
|
-
|
|
8896
|
+
return this.knownTerminals().find((tty) => tty.name === name2);
|
|
8897
|
+
}
|
|
8898
|
+
terminalNames() {
|
|
8899
|
+
return this.knownTerminals().flatMap((tty) => tty.name ? [tty.name] : []);
|
|
8900
|
+
}
|
|
8901
|
+
knownTerminals() {
|
|
8902
|
+
return [.../* @__PURE__ */ new Set([...this.terminals.values(), ...this.foreground.keys()])];
|
|
8823
8903
|
}
|
|
8824
8904
|
controllingTerminal(pid) {
|
|
8825
8905
|
const member = this.members.get(pid);
|
|
@@ -10453,6 +10533,7 @@ var Launcher = class {
|
|
|
10453
10533
|
this.settling.syscall(pid, call.op);
|
|
10454
10534
|
},
|
|
10455
10535
|
...req.ignored ? { ignored: req.ignored } : {},
|
|
10536
|
+
...req.umask !== void 0 ? { umask: req.umask } : {},
|
|
10456
10537
|
program: req.program,
|
|
10457
10538
|
argv0: req.argv0,
|
|
10458
10539
|
args: req.args,
|
|
@@ -10544,7 +10625,8 @@ var Launcher = class {
|
|
|
10544
10625
|
...described,
|
|
10545
10626
|
started: (this.described.get(root.pid) ?? described).started,
|
|
10546
10627
|
state: this.processes.has(member.pid) ? "S" : "Z",
|
|
10547
|
-
memory: this.processes.get(member.pid)?.memory() ?? 0
|
|
10628
|
+
memory: this.processes.get(member.pid)?.memory() ?? 0,
|
|
10629
|
+
umask: this.umaskOf(member.pid)
|
|
10548
10630
|
});
|
|
10549
10631
|
}
|
|
10550
10632
|
return listed;
|
|
@@ -10566,6 +10648,7 @@ var Launcher = class {
|
|
|
10566
10648
|
report,
|
|
10567
10649
|
ppid,
|
|
10568
10650
|
ignored: this.ignoredBy(ppid),
|
|
10651
|
+
umask: this.umaskOf(ppid),
|
|
10569
10652
|
...exec
|
|
10570
10653
|
});
|
|
10571
10654
|
deciding?.attach();
|
|
@@ -10610,7 +10693,8 @@ var Launcher = class {
|
|
|
10610
10693
|
fds,
|
|
10611
10694
|
ppid,
|
|
10612
10695
|
fork: state,
|
|
10613
|
-
ignored: this.ignoredBy(ppid, true)
|
|
10696
|
+
ignored: this.ignoredBy(ppid, true),
|
|
10697
|
+
umask: this.umaskOf(ppid)
|
|
10614
10698
|
})
|
|
10615
10699
|
);
|
|
10616
10700
|
}
|
|
@@ -10619,6 +10703,9 @@ var Launcher = class {
|
|
|
10619
10703
|
const foreground = () => this.jobs.tcgetpgrp(tty, fallback);
|
|
10620
10704
|
this.settling.deliver(sig, pgid, send, tty.reading ? void 0 : foreground);
|
|
10621
10705
|
}
|
|
10706
|
+
umaskOf(pid) {
|
|
10707
|
+
return this.processes.get(pid)?.umask?.() ?? DEFAULT_UMASK;
|
|
10708
|
+
}
|
|
10622
10709
|
ignoredBy(pid, fork = false) {
|
|
10623
10710
|
return this.processes.get(pid)?.ignoredSignals(fork) ?? 0;
|
|
10624
10711
|
}
|