Skip to content

Commit

Permalink
some work on localFS
Browse files Browse the repository at this point in the history
  • Loading branch information
ProgrammerIn-wonderland committed Sep 19, 2024
1 parent b10c446 commit cd1e11f
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 33 deletions.
3 changes: 2 additions & 1 deletion src/api/Filesystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const AnuraFDSymbol = Symbol.for("AnuraFD");
type AnuraFD = {
fd: number;
[AnuraFDSymbol]: string;
path?: string;
};

abstract class AnuraFSOperations<TStats> {
Expand Down Expand Up @@ -989,7 +990,7 @@ class AnuraFilesystem implements AnuraFSOperations<any> {
if (!path.startsWith("/")) {
throw new Error("Path must be absolute");
}
path = path.replace(/^\/+/, "/");
path = path.replace(/\/\//g, "/");

let provider = this.providerCache[path];
if (provider) {
Expand Down
148 changes: 116 additions & 32 deletions src/api/LocalFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class LocalFSStats {
}

class LocalFS extends AFSProvider<LocalFSStats> {
stats: any;
dirHandle: FileSystemDirectoryHandle;
domain: string;
name = "LocalFS";
Expand Down Expand Up @@ -89,6 +90,20 @@ class LocalFS extends AFSProvider<LocalFSStats> {
}
const fs = new LocalFS(dirHandle, anuraPath);
anura.fs.installProvider(fs);
try {
fs.stats = JSON.parse(
new TextDecoder().decode(
await fs.promises.readFile(
anuraPath + "/.anura-fs-stats.json",
),
),
);
} catch (e) {
anura.fs.promises.writeFile(
anuraPath + "/.anura-fs-stats.json",
"{}",
);
}
return fs;
}
static async new(anuraPath: string) {
Expand Down Expand Up @@ -281,7 +296,8 @@ class LocalFS extends AFSProvider<LocalFSStats> {
);
const nodes: string[] = [];
for await (const entry of dirHandle.values()) {
nodes.push(entry.name);
if (entry.name !== ".anura-fs-stats.json")
nodes.push(entry.name);
}
return nodes;
},
Expand Down Expand Up @@ -346,11 +362,14 @@ class LocalFS extends AFSProvider<LocalFSStats> {
} catch (e) {
try {
const handle = await this.getChildDirHandle(path);
return new LocalFSStats({
name: handle.name,
mode: 0o40777,
type: "DIRECTORY",
});
let fstats: any = {};
if (this.stats[path]) {
fstats = this.stats[path];
}
fstats.name ||= handle.name;
fstats.mode ||= 0o40777;
fstats.type ||= "DIRECTORY";
return new LocalFSStats(fstats);
} catch (e) {
throw {
name: "ENOENT",
Expand All @@ -362,27 +381,52 @@ class LocalFS extends AFSProvider<LocalFSStats> {
};
}
}
let fstats: any = {};
if (this.stats[path]) {
fstats = this.stats[path];
}
const file = await handle.getFile();
return new LocalFSStats({
name: file.name,
size: file.size,
});
fstats.name ||= file.name;
fstats.size ||= file.size;

return new LocalFSStats(fstats);
},
truncate: async (path: string, len: number) => {
const data = await this.promises.readFile(path);
await this.promises.writeFile(path, data.slice(0, len));
},
access: () => {
console.error("Not implemented: access");
throw new Error("Not implemented");
access: async (path: string) => {
await this.stat(path);
},
chown: () => {
console.error("Not implemented: chown");
throw new Error("Not implemented");
chown: async (path: string, uid: number, gid: number) => {
await this.promises.access(path);
path = this.relativizePath(path);
if (this.stats[path]) {
this.stats[path].uid = uid;
this.stats[path].gid = gid;
} else {
this.stats[path] = { uid: uid, gid: gid };
}
await anura.fs.promises.writeFile(
this.domain + "/.anura-fs-stats.json",
JSON.stringify(this.stats),
);
},
chmod: () => {
console.error("Not implemented: chmod");
throw new Error("Not implemented");
chmod: async (path: string, mode: number) => {
await this.promises.access(path);
path = this.relativizePath(path);
if (mode < 0o100000) mode += 0o100000;
if (this.stats[path]) {
this.stats[path].mode = mode;
} else {
this.stats[path] = { mode: mode };
}
await anura.fs.promises.writeFile(
this.domain + "/.anura-fs-stats.json",
JSON.stringify(this.stats),
);
// console.error("Not implemented: chmod");
// throw new Error("Not implemented");
},
getxattr: () => {
console.error("Not implemented: getxattr");
Expand Down Expand Up @@ -422,6 +466,7 @@ class LocalFS extends AFSProvider<LocalFSStats> {
this.fds.push(handle);
return {
fd: this.fds.length - 1,
path: path, //for internal stuff
[AnuraFDSymbol]: this.domain,
};
},
Expand All @@ -447,9 +492,35 @@ class LocalFS extends AFSProvider<LocalFSStats> {
},
};

ftruncate() {
console.error("Not implemented: ftruncate");
throw new Error("Method not implemented.");
ftruncate(fd: AnuraFD, ...rest: any[]) {
let cb = rest[2];
const handle = this.fds[fd.fd];
let len = 0;
if (!cb) {
len = rest[1];
} else {
cb = rest[1];
}

if (handle === undefined) {
cb({
name: "EBADF",
code: "EBADF",
errno: 9,
message: "bad file descriptor",
stack: "Error: bad file descriptor",
} as Error);
return;
}

this.promises
.truncate(fd.path!, len)
.then(() => {
cb();
})
.catch((err) => {
cb(err);
});
}

fstat(fd: AnuraFD, callback: (err: Error | null, stats: any) => void) {
Expand Down Expand Up @@ -515,9 +586,18 @@ class LocalFS extends AFSProvider<LocalFSStats> {
throw new Error("Method not implemented.");
}

access() {
console.error("Not implemented: access");
throw new Error("Method not implemented.");
access(path: string, ...rest: any[]) {
let cb = (e: Error) => {};
if (typeof rest[1] === "function") {
cb = rest[1];
}
if (typeof rest[2] === "function") {
cb = rest[2];
}
this.promises
.access(path)
.then(() => {})
.catch((e) => cb(e));
}

mkdtemp() {
Expand All @@ -530,19 +610,22 @@ class LocalFS extends AFSProvider<LocalFSStats> {
throw new Error("Method not implemented.");
}

chmod() {
console.error("Not implemented: chmod");
throw new Error("Method not implemented.");
chmod(path: string, ...rest: any[]) {
const cb = rest[2];
this.promises
.chmod(path, rest[1])
.then(() => {})
.catch((e) => cb(e));
}

fchmod() {
console.error("Not implemented: fchmod");
throw new Error("Method not implemented.");
}

fsync() {
console.error("Not implemented: fsync");
throw new Error("Method not implemented.");
fsync(fd: AnuraFD, callback?: (err: Error | null) => void) {
// we're always sync
if (callback) callback(null);
}

write(
Expand Down Expand Up @@ -600,7 +683,7 @@ class LocalFS extends AFSProvider<LocalFSStats> {
console.error("Not implemented: read");
throw new Error("Method not implemented.");
}

// From here to below are not in normal nodejs
setxattr() {
console.error("Not implemented: setxattr");
throw new Error("Method not implemented.");
Expand Down Expand Up @@ -630,6 +713,7 @@ class LocalFS extends AFSProvider<LocalFSStats> {
console.error("Not implemented: fremovexattr");
throw new Error("Method not implemented.");
}
// below

utimes() {
console.error("Not implemented: utimes");
Expand Down

0 comments on commit cd1e11f

Please sign in to comment.