Skip to content

Commit d7c0261

Browse files
author
Stanislaw Krowicki
committed
[#53124] Cleanup the ProcDirectory node handling
1 parent 41e05f1 commit d7c0261

2 files changed

Lines changed: 86 additions & 116 deletions

File tree

src/filesystem/proc-filesystem/proc-tree.ts

Lines changed: 74 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,46 @@ abstract class AbstractProcDirectory implements ProcDirectory {
105105

106106
constructor(protected pid: number) {}
107107

108+
protected abstract getSpecialNodes(): Record<
109+
string,
110+
new (pid: number) => ProcNode
111+
>;
112+
108113
getFilestat(): Filestat {
109114
return AbstractProcDirectory.filestat;
110115
}
111116

112-
abstract listNodes(): { err: number; nodes: Record<string, ProcNode> };
113-
abstract getNode(path: string): { err: number; node?: ProcNode };
117+
listNodes(): { err: number; nodes: Record<string, ProcNode> } {
118+
let nodes: Record<string, ProcNode> = {};
119+
120+
for (const [name, callback] of Object.entries(this.getSpecialNodes()))
121+
nodes[name] = new callback(this.pid);
122+
123+
return {
124+
err: constants.WASI_ESUCCESS,
125+
nodes,
126+
};
127+
}
128+
129+
getNode(name: string): { err: number; node?: ProcNode } {
130+
if (name === "")
131+
return {
132+
err: constants.WASI_ESUCCESS,
133+
node: this,
134+
};
135+
136+
if (name in this.getSpecialNodes()) {
137+
return {
138+
err: constants.WASI_ESUCCESS,
139+
node: new (this.getSpecialNodes()[name])(this.pid),
140+
};
141+
} else {
142+
return {
143+
err: constants.WASI_ENOENT,
144+
node: undefined,
145+
};
146+
}
147+
}
114148
}
115149

116150
class MountinfoFile extends AbstractProcFile {
@@ -258,70 +292,55 @@ class ResetFile extends AbstractProcFile {
258292
}
259293

260294
class SysDirectory extends AbstractProcDirectory implements ProcNode {
261-
static specialNodes: Record<string, new (pid: number) => ProcNode> = {
295+
private static readonly specialNodes: Record<
296+
string,
297+
new (pid: number) => ProcNode
298+
> = {
262299
reset: ResetFile,
263300
};
264301

265-
listNodes(): { err: number; nodes: Record<string, ProcNode> } {
266-
let nodes: Record<string, ProcNode> = {};
267-
268-
for (const [name, callback] of Object.entries(SysDirectory.specialNodes))
269-
nodes[name] = new callback(this.pid);
270-
271-
return {
272-
err: constants.WASI_ESUCCESS,
273-
nodes,
274-
};
275-
}
276-
277-
getNode(name: string): { err: number; node?: ProcNode } {
278-
if (name === "") {
279-
return { err: constants.WASI_ESUCCESS, node: this };
280-
}
281-
282-
if (name === "reset") {
283-
return {
284-
err: constants.WASI_ESUCCESS,
285-
node: new ResetFile(),
286-
};
287-
}
288-
return {
289-
err: constants.WASI_ENOENT,
290-
node: undefined,
291-
};
302+
protected override getSpecialNodes(): Record<
303+
string,
304+
new (pid: number) => ProcNode
305+
> {
306+
return SysDirectory.specialNodes;
292307
}
293308
}
294309

295310
export class TopLevelDirectory extends AbstractProcDirectory {
296-
static specialNodes: Record<string, new (pid: number) => ProcNode> = {
311+
private static readonly specialNodes: Record<
312+
string,
313+
new (pid: number) => ProcNode
314+
> = {
297315
self: SelfSymlink,
298316
sys: SysDirectory,
317+
// Add meminfo only for browsers that support performance.memory API
318+
// (so Chromium based)
319+
...((performance as any).memory !== undefined
320+
? { meminfo: MeminfoFile }
321+
: {}),
299322
};
300323

301-
listNodes(): { err: number; nodes: Record<string, ProcNode> } {
302-
let nodes: Record<string, ProcNode> = {};
324+
protected override getSpecialNodes(): Record<
325+
string,
326+
new (pid: number) => ProcNode
327+
> {
328+
return TopLevelDirectory.specialNodes;
329+
}
303330

304-
for (const [name, callback] of Object.entries(
305-
TopLevelDirectory.specialNodes,
306-
))
307-
nodes[name] = new callback(this.pid);
331+
override listNodes(): { err: number; nodes: Record<string, ProcNode> } {
332+
let nodes: Record<string, ProcNode> = super.listNodes().nodes;
308333

309334
for (const pid of Object.keys(processManager.processInfos))
310335
nodes[pid.toString()] = new ProcessDirectory(Number(pid));
311336

312-
if ((performance as any).memory !== undefined) {
313-
// Add meminfo only for browsers that support memory.performance API
314-
// (so Chromium-based)
315-
nodes["meminfo"] = new MeminfoFile();
316-
}
317-
318337
return {
319338
err: constants.WASI_ESUCCESS,
320339
nodes,
321340
};
322341
}
323342

324-
getNode(name: string): { err: number; node?: ProcNode } {
343+
override getNode(name: string): { err: number; node?: ProcNode } {
325344
if (name === "") {
326345
return { err: constants.WASI_ESUCCESS, node: this };
327346
}
@@ -334,87 +353,28 @@ export class TopLevelDirectory extends AbstractProcDirectory {
334353
node: new ProcessDirectory(num),
335354
};
336355
}
337-
} else if (name === "self") {
338-
return {
339-
err: constants.WASI_ESUCCESS,
340-
node: new SelfSymlink(this.pid),
341-
};
342-
} else if (
343-
name === "meminfo" &&
344-
(performance as any).memory !== undefined
345-
) {
346-
return {
347-
err: constants.WASI_ESUCCESS,
348-
node: new MeminfoFile(),
349-
};
350-
} else if (name === "sys") {
351-
return {
352-
err: constants.WASI_ESUCCESS,
353-
node: new SysDirectory(this.pid),
354-
};
355356
}
356-
return {
357-
err: constants.WASI_ENOENT,
358-
node: undefined,
359-
};
357+
358+
return super.getNode(name);
360359
}
361360
}
362361

363362
class ProcessDirectory extends AbstractProcDirectory implements ProcNode {
364-
static specialNodes: Record<string, new (pid: number) => ProcNode> = {
363+
private static readonly specialNodes: Record<
364+
string,
365+
new (pid: number) => ProcNode
366+
> = {
365367
mountinfo: MountinfoFile,
366368
status: StatusFile,
367369
environ: EnvironFile,
368370
stat: StatFile,
369371
cwd: CwdSymlink,
370372
};
371373

372-
listNodes(): { err: number; nodes: Record<string, ProcNode> } {
373-
let nodes: Record<string, ProcNode> = {};
374-
375-
for (const [name, callback] of Object.entries(
376-
ProcessDirectory.specialNodes,
377-
))
378-
nodes[name] = new callback(this.pid);
379-
380-
return {
381-
err: constants.WASI_ESUCCESS,
382-
nodes,
383-
};
384-
}
385-
386-
getNode(name: string): { err: number; node?: ProcNode } {
387-
switch (name) {
388-
case "mountinfo":
389-
return {
390-
err: constants.WASI_ESUCCESS,
391-
node: new MountinfoFile(),
392-
};
393-
case "status":
394-
return {
395-
err: constants.WASI_ESUCCESS,
396-
node: new StatusFile(this.pid),
397-
};
398-
case "environ":
399-
return {
400-
err: constants.WASI_ESUCCESS,
401-
node: new EnvironFile(this.pid),
402-
};
403-
case "stat":
404-
return {
405-
err: constants.WASI_ESUCCESS,
406-
node: new StatFile(this.pid),
407-
};
408-
case "cwd":
409-
return {
410-
err: constants.WASI_ESUCCESS,
411-
node: new CwdSymlink(this.pid),
412-
};
413-
default:
414-
return {
415-
err: constants.WASI_ENOENT,
416-
node: undefined,
417-
};
418-
}
374+
protected override getSpecialNodes(): Record<
375+
string,
376+
new (pid: number) => ProcNode
377+
> {
378+
return ProcessDirectory.specialNodes;
419379
}
420380
}

tests/unit/proc-tree.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,25 @@ describe("Test proc tree", () => {
201201
configurable: true,
202202
});
203203

204+
let topLevelNode;
205+
206+
jest.isolateModules(() => {
207+
// Used to reload the specialNodes records with performance.memory available
208+
const isolatedProc = require("../../src/filesystem/proc-filesystem/proc-tree");
209+
isolatedProc.initialize(processManager);
210+
211+
topLevelNode = isolatedProc.getTopLevelNode(pid);
212+
});
213+
204214
jest
205215
.spyOn(processManager, "processInfos", "get")
206216
.mockReturnValue(dummyProcessInfos(pid));
207217

208-
const nodes = topLevelNode.listNodes();
218+
const nodes = topLevelNode!.listNodes();
209219
expect(nodes.err).toBe(constants.WASI_ESUCCESS);
210220
expect(Object.keys(nodes.nodes)).toContain("meminfo");
211221

212-
const meminfoFile = topLevelNode.getNode("meminfo");
222+
const meminfoFile = topLevelNode!.getNode("meminfo");
213223
expect(meminfoFile.err).toBe(constants.WASI_ESUCCESS);
214224

215225
const contents = (meminfoFile.node as proc.ProcFile).read();

0 commit comments

Comments
 (0)