Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/core/kernel/src/wasm/posix/stat.ts
1068 views
1
import { isAbsolute, join } from "path";
2
import constants from "./constants";
3
import Errno from "./errno";
4
import { notImplemented } from "./util";
5
6
export default function stats({ fs, process, recv, wasi }) {
7
function calculateAt(
8
dirfd: number,
9
path: string,
10
allowEmpty: boolean = false
11
) {
12
if (isAbsolute("path")) {
13
return path;
14
}
15
16
let dir: string;
17
if (dirfd == constants.AT_FDCWD) {
18
dir = process.cwd?.() ?? "/";
19
} else {
20
// it is a file descriptor
21
const entry = wasi.FD_MAP.get(dirfd);
22
if (!entry) {
23
throw Errno("EBADF");
24
}
25
dir = entry.path;
26
}
27
if (path.length == 0) {
28
if (!allowEmpty) {
29
throw Errno("ENOENT");
30
}
31
return dir;
32
}
33
return join(dir, path);
34
}
35
36
// because wasi's structs don't have sufficient info to deal with permissions, we make ALL of these
37
// chmods into stubs, below, despite having implemented them!
38
// This in particular totally broke libgit2 working at all.
39
// TODO: an alternative may be to always set the mode to 0777. I'm not sure how bad that would be.
40
return {
41
chmod: (pathPtr: number, mode: number): -1 | 0 => {
42
return 0; // stubbed due to wasi shortcomings
43
if (!mode) {
44
// It is impossible for stat calls by wasi to return anything except 0 at present due to this bug:
45
// See https://github.com/WebAssembly/wasi-filesystem/issues/34
46
// Thus they will often then set the mode to 0, e.g., shutil.copy in python does this to all files.
47
// In such cases, we silently make this a successful no-op instead of breaking everything horribly.
48
// This comes up a lot with using Python as part of a build process.
49
return 0;
50
}
51
const path = recv.string(pathPtr);
52
fs.chmodSync(path, mode);
53
return 0;
54
},
55
56
_fchmod: (fd: number, mode: number): number => {
57
return 0; // stubbed due to wasi shortcomings
58
if (!mode) {
59
// see above.
60
return 0;
61
}
62
const entry = wasi.FD_MAP.get(fd);
63
if (!entry) {
64
console.warn("bad file descriptor, fchmod");
65
return -1;
66
}
67
fs.fchmodSync(entry.real, mode);
68
return 0;
69
},
70
71
// int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);
72
fchmodat: (
73
dirfd: number,
74
pathPtr: number,
75
mode: number,
76
_flags: number
77
): number => {
78
return 0; // stubbed due to wasi shortcomings
79
if (!mode) {
80
// see above.
81
return 0;
82
}
83
/* "The fchmodat() system call operates in exactly the same way as chmod(2), except... If the
84
pathname given in pathname is relative, then it is interpreted relative to the directory referred
85
to by the file descriptor dirfd (rather than relative to the current working directory of the
86
calling process, as is done by chmod(2) for a relative pathname). If pathname is relative and
87
dirfd is the special value AT_FDCWD, then pathname is interpreted relative to the current
88
working directory of the calling process (like chmod(2)). If pathname is absolute, then dirfd
89
is ignored. This flag is not currently implemented."
90
*/
91
const path = recv.string(pathPtr);
92
const pathAt = calculateAt(dirfd, path);
93
fs.chmodSync(pathAt, mode);
94
return 0;
95
},
96
97
lchmod: (pathPtr: number, mode: number): -1 | 0 => {
98
return 0; // stubbed due to wasi shortcomings
99
if (!mode) {
100
// see above.
101
return 0;
102
}
103
const path = recv.string(pathPtr);
104
fs.lchmodSync(path, mode);
105
return 0;
106
},
107
108
// mode_t umask(mode_t mask);
109
umask: (mask: number) => {
110
// we return 18 when there's no process.umask function, since that's
111
// like umask 022, i.e., it's a reasonable default.
112
return process.umask?.(mask) ?? 18;
113
},
114
115
// not in wasi and we haven't done it yet...
116
mkfifo: () => {
117
notImplemented("mkfifo");
118
},
119
120
mknod: () => {
121
notImplemented("mknod");
122
},
123
};
124
}
125
126