Skip to content

Commit 0882eb3

Browse files
committed
fs_mem: add InodeMem to track atim/mtim/ctim
1 parent 0d34b85 commit 0882eb3

File tree

2 files changed

+103
-15
lines changed

2 files changed

+103
-15
lines changed

src/fs_mem.ts

Lines changed: 102 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ export class OpenFile extends Fd {
7070
return wasi.ERRNO_SUCCESS;
7171
}
7272

73+
fd_filestat_set_times(atim: bigint, mtim: bigint, fst_flags: number): number {
74+
return this.file.set_times(atim, mtim, fst_flags);
75+
}
76+
7377
fd_read(size: number): { ret: number; data: Uint8Array } {
7478
const slice = this.file.data.slice(
7579
Number(this.file_pos),
@@ -237,11 +241,31 @@ export class OpenDirectory extends Fd {
237241
return { ret: 0, filestat: entry.stat() };
238242
}
239243

244+
path_filestat_set_times(
245+
_flags: number,
246+
path_str: string,
247+
atim: bigint,
248+
mtim: bigint,
249+
fst_flags: number,
250+
): number {
251+
const { ret: path_err, path } = Path.from(path_str);
252+
if (path == null) {
253+
return path_err;
254+
}
255+
256+
const { ret, entry } = this.dir.get_entry_for_path(path);
257+
if (entry == null) {
258+
return ret;
259+
}
260+
261+
return entry.set_times(atim, mtim, fst_flags);
262+
}
263+
240264
path_lookup(
241265
path_str: string,
242266
// eslint-disable-next-line @typescript-eslint/no-unused-vars
243267
dirflags: number,
244-
): { ret: number; inode_obj: Inode | null } {
268+
): { ret: number; inode_obj: InodeMem | null } {
245269
const { ret: path_ret, path } = Path.from(path_str);
246270
if (path == null) {
247271
return { ret: path_ret, inode_obj: null };
@@ -315,7 +339,7 @@ export class OpenDirectory extends Fd {
315339
).ret;
316340
}
317341

318-
path_link(path_str: string, inode: Inode, allow_dir: boolean): number {
342+
path_link(path_str: string, inode: InodeMem, allow_dir: boolean): number {
319343
const { ret: path_ret, path } = Path.from(path_str);
320344
if (path == null) {
321345
return path_ret;
@@ -374,7 +398,7 @@ export class OpenDirectory extends Fd {
374398
return wasi.ERRNO_SUCCESS;
375399
}
376400

377-
path_unlink(path_str: string): { ret: number; inode_obj: Inode | null } {
401+
path_unlink(path_str: string): { ret: number; inode_obj: InodeMem | null } {
378402
const { ret: path_ret, path } = Path.from(path_str);
379403
if (path == null) {
380404
return { ret: path_ret, inode_obj: null };
@@ -461,6 +485,10 @@ export class OpenDirectory extends Fd {
461485
return wasi.ERRNO_BADF;
462486
}
463487

488+
fd_filestat_set_times(atim: bigint, mtim: bigint, fst_flags: number): number {
489+
return this.dir.set_times(atim, mtim, fst_flags);
490+
}
491+
464492
// eslint-disable-next-line @typescript-eslint/no-unused-vars
465493
fd_read(size: number): { ret: number; data: Uint8Array } {
466494
return { ret: wasi.ERRNO_BADF, data: new Uint8Array() };
@@ -489,7 +517,7 @@ export class OpenDirectory extends Fd {
489517
export class PreopenDirectory extends OpenDirectory {
490518
prestat_name: string;
491519

492-
constructor(name: string, contents: Map<string, Inode>) {
520+
constructor(name: string, contents: Map<string, InodeMem>) {
493521
super(new Directory(contents));
494522
this.prestat_name = name;
495523
}
@@ -502,7 +530,51 @@ export class PreopenDirectory extends OpenDirectory {
502530
}
503531
}
504532

505-
export class File extends Inode {
533+
function realtime(): bigint {
534+
return BigInt(Date.now()) * 1000000n;
535+
}
536+
537+
export abstract class InodeMem extends Inode {
538+
atim: bigint;
539+
mtim: bigint;
540+
ctim: bigint;
541+
542+
constructor() {
543+
super();
544+
const now = realtime();
545+
this.atim = now;
546+
this.mtim = now;
547+
this.ctim = now;
548+
}
549+
550+
set_times(atim: bigint, mtim: bigint, fst_flags: number): number {
551+
const now = realtime();
552+
553+
if (fst_flags & wasi.FSTFLAGS_ATIM) {
554+
this.atim = atim;
555+
this.ctim = now;
556+
}
557+
558+
if (fst_flags & wasi.FSTFLAGS_ATIM_NOW) {
559+
this.atim = now;
560+
this.ctim = now;
561+
}
562+
563+
if (fst_flags & wasi.FSTFLAGS_MTIM) {
564+
this.mtim = mtim;
565+
this.ctim = now;
566+
}
567+
568+
if (fst_flags & wasi.FSTFLAGS_MTIM_NOW) {
569+
this.mtim = now;
570+
this.ctim = now;
571+
}
572+
573+
return wasi.ERRNO_SUCCESS;
574+
}
575+
}
576+
577+
export class File extends InodeMem {
506578
data: Uint8Array;
507579
readonly: boolean;
508580

@@ -542,7 +614,14 @@ export class File extends Inode {
542614
}
543615

544616
stat(): wasi.Filestat {
545-
return new wasi.Filestat(this.ino, wasi.FILETYPE_REGULAR_FILE, this.size);
617+
return new wasi.Filestat(
618+
this.ino,
619+
wasi.FILETYPE_REGULAR_FILE,
620+
this.size,
621+
this.atim,
622+
this.mtim,
623+
this.ctim,
624+
);
546625
}
547626
}
548627

@@ -586,11 +665,11 @@ class Path {
586665
}
587666
}
588667

589-
export class Directory extends Inode {
590-
contents: Map<string, Inode>;
668+
export class Directory extends InodeMem {
669+
contents: Map<string, InodeMem>;
591670
parent: Directory | null = null;
592671

593-
constructor(contents: Map<string, Inode> | [string, Inode][]) {
672+
constructor(contents: Map<string, InodeMem> | [string, InodeMem][]) {
594673
super();
595674
if (contents instanceof Array) {
596675
this.contents = new Map(contents);
@@ -618,11 +697,18 @@ export class Directory extends Inode {
618697
}
619698

620699
stat(): wasi.Filestat {
621-
return new wasi.Filestat(this.ino, wasi.FILETYPE_DIRECTORY, 0n);
700+
return new wasi.Filestat(
701+
this.ino,
702+
wasi.FILETYPE_DIRECTORY,
703+
0n,
704+
this.atim,
705+
this.mtim,
706+
this.ctim,
707+
);
622708
}
623709

624-
get_entry_for_path(path: Path): { ret: number; entry: Inode | null } {
625-
let entry: Inode = this;
710+
get_entry_for_path(path: Path): { ret: number; entry: InodeMem | null } {
711+
let entry: InodeMem = this;
626712
for (const component of path.parts) {
627713
if (!(entry instanceof Directory)) {
628714
return { ret: wasi.ERRNO_NOTDIR, entry: null };
@@ -652,7 +738,7 @@ export class Directory extends Inode {
652738
ret: number;
653739
parent_entry: Directory | null;
654740
filename: string | null;
655-
entry: Inode | null;
741+
entry: InodeMem | null;
656742
} {
657743
const filename = path.parts.pop();
658744

@@ -683,7 +769,8 @@ export class Directory extends Inode {
683769
entry: null,
684770
};
685771
}
686-
const entry: Inode | undefined | null = parent_entry.contents.get(filename);
772+
const entry: InodeMem | undefined | null =
773+
parent_entry.contents.get(filename);
687774
if (entry === undefined) {
688775
if (!allow_undefined) {
689776
return {
@@ -714,7 +801,7 @@ export class Directory extends Inode {
714801
create_entry_for_path(
715802
path_str: string,
716803
is_dir: boolean,
717-
): { ret: number; entry: Inode | null } {
804+
): { ret: number; entry: InodeMem | null } {
718805
const { ret: path_ret, path } = Path.from(path_str);
719806
if (path == null) {
720807
return { ret: path_ret, entry: null };

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export { Fd, Inode } from "./fd.js";
55
export {
66
File,
77
Directory,
8+
InodeMem,
89
OpenFile,
910
OpenDirectory,
1011
PreopenDirectory,

0 commit comments

Comments
 (0)