@k13engineering/linux-fuse 0.0.7 → 0.1.0
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/dist/lib/abi.d.ts +1133 -5
- package/dist/lib/abi.js +705 -535
- package/dist/lib/constants.d.ts +5 -3
- package/dist/lib/constants.js +10 -8
- package/dist/lib/convenience.js +344 -344
- package/dist/lib/dirent.js +24 -8
- package/dist/lib/filesystem.d.ts +41 -0
- package/dist/lib/filesystem.js +344 -0
- package/dist/lib/fuse-lowlevel.d.ts +3 -1
- package/dist/lib/fuse-lowlevel.js +17 -4
- package/dist/lib/index.d.ts +3 -33
- package/dist/lib/index.js +11 -283
- package/dist/lib/kernel.d.ts +9 -0
- package/dist/lib/kernel.js +21 -0
- package/dist/lib/linux-fuse.d.ts +21 -0
- package/dist/lib/linux-fuse.js +38 -0
- package/dist/lib/linux.d.ts +3 -1
- package/dist/lib/linux.js +16 -9
- package/dist/lib/message.js +6 -0
- package/dist/lib/mount.d.ts +5 -2
- package/dist/lib/mount.js +16 -4
- package/dist/lib/protocol.d.ts +6 -0
- package/dist/lib/protocol.js +861 -830
- package/dist/lib/server.js +33 -0
- package/dist/lib/syscalls.d.ts +66 -38
- package/dist/lib/syscalls.js +281 -198
- package/package.json +4 -4
package/dist/lib/index.js
CHANGED
|
@@ -1,292 +1,20 @@
|
|
|
1
|
-
import { createFuseLowLevel } from "./fuse-lowlevel.js";
|
|
2
|
-
import { createFuseServer, /*type TRequestHandler */} from "./server.js";
|
|
3
|
-
import {
|
|
4
|
-
FSCONFIG_CMD_CREATE,
|
|
5
|
-
FSCONFIG_SET_FLAG,
|
|
6
|
-
FSCONFIG_SET_STRING,
|
|
7
|
-
FSMOUNT_CLOEXEC,
|
|
8
|
-
FSOPEN_CLOEXEC,
|
|
9
|
-
} from "./constants.js";
|
|
10
|
-
import nodeFs from "node:fs";
|
|
11
|
-
import { fchdir, fsconfig, fsmount, fsopen } from "./syscalls.js";
|
|
12
|
-
import { openFuseFd, defaultFusePath } from "./linux.js";
|
|
13
1
|
import { createConvenienceRequestHandler } from "./convenience.js";
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
/*type TMountAttributes,
|
|
19
|
-
*//*type TRequiredFuseMountOptions
|
|
20
|
-
*/} from "./mount.js";
|
|
21
|
-
import { createPoller } from "@k13engineering/uv-poll";
|
|
2
|
+
import { linuxKernel } from "./kernel.js";
|
|
3
|
+
import { createLinuxFuse } from "./linux-fuse.js";
|
|
4
|
+
import { defaultFusePath } from "./linux.js";
|
|
5
|
+
/*import type { TMountAttributes, TRequiredFuseMountOptions } from "./mount.ts";*/
|
|
22
6
|
/*import type { TFuseResponse } from "./protocol.ts";*/
|
|
23
7
|
/*import type { TFuseServerInterface } from "./convenience.ts";*/
|
|
24
8
|
/*import type { TDirent } from "./dirent.ts";*/
|
|
25
9
|
import { direntsToBuffer } from "./dirent.js";
|
|
26
10
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
sniff,
|
|
35
|
-
}/*: {
|
|
36
|
-
fuseFd: number;
|
|
37
|
-
requestHandler: TRequestHandler;
|
|
38
|
-
|
|
39
|
-
sniff?: {
|
|
40
|
-
rawMessageFromKernel: (args: { data: Uint8Array }) => void;
|
|
41
|
-
rawMessageToKernel: (args: { data: Uint8Array }) => void;
|
|
42
|
-
}
|
|
43
|
-
}*/) => {
|
|
44
|
-
|
|
45
|
-
let lowLevel = createFuseLowLevel({
|
|
46
|
-
fuseFd,
|
|
47
|
-
maxMessageSize: 1 * 1024 * 1024 + 4096,
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const server = createFuseServer({
|
|
51
|
-
requestHandler: {
|
|
52
|
-
// eslint-disable-next-line complexity
|
|
53
|
-
handleRequest: async ({ request }) => {
|
|
54
|
-
const response = await requestHandler.handleRequest({ request });
|
|
55
|
-
|
|
56
|
-
if (response !== undefined && response.forOpcode === "INIT" && response.errorCode === undefined) {
|
|
57
|
-
|
|
58
|
-
if (response.result.maxWrite >= MAX_ALLOWED_WRITE) {
|
|
59
|
-
throw Error(`maxWrite of ${response.result.maxWrite} is too large, refusing to operate`);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
lowLevel = createFuseLowLevel({
|
|
63
|
-
fuseFd,
|
|
64
|
-
maxMessageSize: Number(response.result.maxWrite) + 4096,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return response;
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
sendMessageToKernel: ({ rawMessageToKernel }) => {
|
|
72
|
-
sniff?.rawMessageToKernel({ data: rawMessageToKernel });
|
|
73
|
-
lowLevel.writeOutgoingMessage({
|
|
74
|
-
rawMessage: rawMessageToKernel
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
80
|
-
let ended = false;
|
|
81
|
-
let closed = false;
|
|
82
|
-
|
|
83
|
-
const poller = createPoller({
|
|
84
|
-
fd: fuseFd
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const handlePollError = ({ errorCode }/*: { errorCode: number }*/) => {
|
|
88
|
-
if (errorCode === UV_EBADF) {
|
|
89
|
-
// EBADF is raised when the kernel unmounts the filesystem
|
|
90
|
-
ended = true;
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
throw Error(`poll error with code ${errorCode}`);
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
// eslint-disable-next-line complexity
|
|
98
|
-
const next = () => {
|
|
99
|
-
|
|
100
|
-
if (closed) {
|
|
101
|
-
throw Error("BUG: should not be called after close");
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const { error: readError, incomingMessage, end } = lowLevel.tryReadIncomingMessage();
|
|
105
|
-
if (readError !== undefined) {
|
|
106
|
-
throw readError;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (end) {
|
|
110
|
-
ended = true;
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (incomingMessage !== undefined) {
|
|
115
|
-
sniff?.rawMessageFromKernel({ data: incomingMessage });
|
|
116
|
-
server.processRequest({
|
|
117
|
-
rawIncomingRequest: incomingMessage
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
poller.armOnce({
|
|
122
|
-
error: ({ errorCode }) => {
|
|
123
|
-
handlePollError({ errorCode });
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
readable: () => {
|
|
127
|
-
next();
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
poller.armOnce({
|
|
133
|
-
error: ({ errorCode }) => {
|
|
134
|
-
handlePollError({ errorCode });
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
readable: () => {
|
|
138
|
-
next();
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
/*type TFsMountResult = {
|
|
143
|
-
error: Error;
|
|
144
|
-
mountFd: undefined;
|
|
145
|
-
} | {
|
|
146
|
-
error: undefined;
|
|
147
|
-
mountFd: number;
|
|
148
|
-
};*/
|
|
149
|
-
|
|
150
|
-
// eslint-disable-next-line max-statements
|
|
151
|
-
const mountDetached = ({
|
|
152
|
-
otherOptions,
|
|
153
|
-
requiredOptions,
|
|
154
|
-
mountAttributes,
|
|
155
|
-
}/*: {
|
|
156
|
-
otherOptions: {
|
|
157
|
-
default_permissions?: boolean;
|
|
158
|
-
allow_other?: boolean;
|
|
159
|
-
allow_root?: boolean;
|
|
160
|
-
} | Record<string, string | boolean>;
|
|
161
|
-
requiredOptions: TRequiredFuseMountOptions;
|
|
162
|
-
mountAttributes: TMountAttributes;
|
|
163
|
-
}*/)/*: TFsMountResult*/ => {
|
|
164
|
-
|
|
165
|
-
const { errno: fsopenErrno, fsfd } = fsopen({
|
|
166
|
-
fileSystemName: "fuse",
|
|
167
|
-
flags: FSOPEN_CLOEXEC
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
if (fsopenErrno !== undefined) {
|
|
171
|
-
return {
|
|
172
|
-
error: Error(`fsopen syscall failed with errno ${fsopenErrno}`),
|
|
173
|
-
mountFd: undefined,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const configureString = ({ key, value }/*: { key: string; value: string }*/) => {
|
|
178
|
-
const { errno } = fsconfig({
|
|
179
|
-
fd: fsfd,
|
|
180
|
-
command: FSCONFIG_SET_STRING,
|
|
181
|
-
key,
|
|
182
|
-
value,
|
|
183
|
-
auxiliaryValue: 0,
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
if (errno !== undefined) {
|
|
187
|
-
throw Error(`fsconfig syscall failed with errno ${errno} when setting ${key}=${value}`);
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const configureFlag = ({ key, value }/*: { key: string; value: boolean }*/) => {
|
|
192
|
-
if (!value) {
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const { errno } = fsconfig({
|
|
197
|
-
fd: fsfd,
|
|
198
|
-
command: FSCONFIG_SET_FLAG,
|
|
199
|
-
key,
|
|
200
|
-
value: undefined,
|
|
201
|
-
auxiliaryValue: 0,
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
if (errno !== undefined) {
|
|
205
|
-
throw Error(`fsconfig syscall failed with errno ${errno} when setting flag ${key}`);
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const forbiddenOptions = ["fd", "rootmode", "user_id", "group_id"];
|
|
210
|
-
|
|
211
|
-
Object.keys(otherOptions).forEach((key) => {
|
|
212
|
-
const value = otherOptions[key /*as keyof typeof otherOptions*/];
|
|
213
|
-
|
|
214
|
-
if (forbiddenOptions.includes(key)) {
|
|
215
|
-
throw Error(`option ${key} is not allowed as it is required for correct mounting`);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (value === undefined) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (typeof value === "boolean") {
|
|
223
|
-
configureFlag({ key, value });
|
|
224
|
-
} else {
|
|
225
|
-
configureString({ key, value });
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
configureString({ key: "fd", value: `${fuseFd}` });
|
|
230
|
-
configureString({ key: "rootmode", value: `${requiredOptions.rootmode.toString(8)}` });
|
|
231
|
-
configureString({ key: "user_id", value: `${requiredOptions.user_id}` });
|
|
232
|
-
configureString({ key: "group_id", value: `${requiredOptions.group_id}` });
|
|
233
|
-
|
|
234
|
-
const { errno: createErrno } = fsconfig({
|
|
235
|
-
fd: fsfd,
|
|
236
|
-
command: FSCONFIG_CMD_CREATE,
|
|
237
|
-
key: undefined,
|
|
238
|
-
value: undefined,
|
|
239
|
-
auxiliaryValue: 0,
|
|
240
|
-
});
|
|
241
|
-
if (createErrno !== undefined) {
|
|
242
|
-
|
|
243
|
-
nodeFs.closeSync(fsfd);
|
|
244
|
-
|
|
245
|
-
return {
|
|
246
|
-
error: Error(`fsconfig CMD_CREATE syscall failed with errno ${createErrno}`),
|
|
247
|
-
mountFd: undefined,
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const { errno: mountErrno, mountFd } = fsmount({
|
|
252
|
-
fd: fsfd,
|
|
253
|
-
flags: FSMOUNT_CLOEXEC,
|
|
254
|
-
mountAttributesBitmask: mountAttributesToBitmask({
|
|
255
|
-
mountAttributes
|
|
256
|
-
})
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
nodeFs.closeSync(fsfd);
|
|
260
|
-
|
|
261
|
-
if (mountErrno !== undefined) {
|
|
262
|
-
return {
|
|
263
|
-
error: Error(`fsmount syscall failed with errno ${mountErrno}`),
|
|
264
|
-
mountFd: undefined,
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
return {
|
|
269
|
-
error: undefined,
|
|
270
|
-
mountFd,
|
|
271
|
-
};
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
const close = () => {
|
|
275
|
-
if (closed) {
|
|
276
|
-
throw Error("already closed");
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
closed = true;
|
|
280
|
-
|
|
281
|
-
poller.close();
|
|
282
|
-
nodeFs.closeSync(fuseFd);
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
return {
|
|
286
|
-
mountDetached,
|
|
287
|
-
close,
|
|
288
|
-
};
|
|
289
|
-
};
|
|
11
|
+
const {
|
|
12
|
+
createFuseFileSystem,
|
|
13
|
+
openFuseFd,
|
|
14
|
+
moveMount,
|
|
15
|
+
unmount,
|
|
16
|
+
fchdir,
|
|
17
|
+
} = createLinuxFuse({ kernel: linuxKernel });
|
|
290
18
|
|
|
291
19
|
const createDefaultInitResult = ()/*: Extract<TFuseResponse, { forOpcode: "INIT", errorCode: undefined }>["result"]*/ => {
|
|
292
20
|
return {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createPoller } from "@k13engineering/uv-poll";
|
|
2
|
+
import { syscall } from "syscall-napi";
|
|
3
|
+
type TKernel = {
|
|
4
|
+
syscall: typeof syscall;
|
|
5
|
+
createPoller: typeof createPoller;
|
|
6
|
+
};
|
|
7
|
+
declare const linuxKernel: TKernel;
|
|
8
|
+
export { linuxKernel, };
|
|
9
|
+
export type { TKernel, };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createPoller } from "@k13engineering/uv-poll";
|
|
2
|
+
import { syscall } from "syscall-napi";
|
|
3
|
+
|
|
4
|
+
// everything that needs the real kernel goes through this interface, so it can be mocked in tests
|
|
5
|
+
/*type TKernel = {
|
|
6
|
+
syscall: typeof syscall;
|
|
7
|
+
createPoller: typeof createPoller;
|
|
8
|
+
};*/
|
|
9
|
+
|
|
10
|
+
const linuxKernel/*: TKernel*/ = {
|
|
11
|
+
syscall,
|
|
12
|
+
createPoller,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
linuxKernel,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/*export type {
|
|
20
|
+
TKernel,
|
|
21
|
+
};*/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type TFuseFileSystemOptions } from "./filesystem.js";
|
|
2
|
+
import type { TKernel } from "./kernel.js";
|
|
3
|
+
declare const createLinuxFuse: ({ kernel }: {
|
|
4
|
+
kernel: TKernel;
|
|
5
|
+
}) => {
|
|
6
|
+
createFuseFileSystem: (options: TFuseFileSystemOptions) => any;
|
|
7
|
+
openFuseFd: ({ fusePath }: {
|
|
8
|
+
fusePath: string;
|
|
9
|
+
}) => any;
|
|
10
|
+
moveMount: ({ mountFd, newMountPoint }: {
|
|
11
|
+
mountFd: number;
|
|
12
|
+
newMountPoint: string;
|
|
13
|
+
}) => any;
|
|
14
|
+
unmount: ({ mountPoint, force, detach }: {
|
|
15
|
+
mountPoint: string;
|
|
16
|
+
force: boolean;
|
|
17
|
+
detach: boolean;
|
|
18
|
+
}) => any;
|
|
19
|
+
fchdir: any;
|
|
20
|
+
};
|
|
21
|
+
export { createLinuxFuse, };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createFuseFileSystem, /*type TFuseFileSystemOptions */} from "./filesystem.js";
|
|
2
|
+
/*import type { TKernel } from "./kernel.ts";*/
|
|
3
|
+
import { openFuseFd } from "./linux.js";
|
|
4
|
+
import { moveMount, unmount } from "./mount.js";
|
|
5
|
+
import { createSyscalls } from "./syscalls.js";
|
|
6
|
+
|
|
7
|
+
// binds the public API to a kernel, the default instance uses the real one
|
|
8
|
+
const createLinuxFuse = ({ kernel }/*: { kernel: TKernel }*/) => {
|
|
9
|
+
const syscalls = createSyscalls({ kernel });
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
createFuseFileSystem: (options/*: TFuseFileSystemOptions*/) => {
|
|
13
|
+
return createFuseFileSystem({
|
|
14
|
+
...options,
|
|
15
|
+
syscalls,
|
|
16
|
+
createPoller: kernel.createPoller,
|
|
17
|
+
});
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
openFuseFd: ({ fusePath }/*: { fusePath: string }*/) => {
|
|
21
|
+
return openFuseFd({ syscalls, fusePath });
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
moveMount: ({ mountFd, newMountPoint }/*: { mountFd: number; newMountPoint: string }*/) => {
|
|
25
|
+
return moveMount({ syscalls, mountFd, newMountPoint });
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
unmount: ({ mountPoint, force, detach }/*: { mountPoint: string; force: boolean; detach: boolean }*/) => {
|
|
29
|
+
return unmount({ syscalls, mountPoint, force, detach });
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
fchdir: syscalls.fchdir,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
createLinuxFuse,
|
|
38
|
+
};
|
package/dist/lib/linux.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TSyscalls } from "./syscalls.js";
|
|
1
2
|
type TOpenResult = {
|
|
2
3
|
error: Error;
|
|
3
4
|
fuseFd: undefined;
|
|
@@ -6,7 +7,8 @@ type TOpenResult = {
|
|
|
6
7
|
fuseFd: number;
|
|
7
8
|
};
|
|
8
9
|
declare const defaultFusePath = "/dev/fuse";
|
|
9
|
-
declare const openFuseFd: ({ fusePath }: {
|
|
10
|
+
declare const openFuseFd: ({ syscalls, fusePath }: {
|
|
11
|
+
syscalls: Pick<TSyscalls, "openat">;
|
|
10
12
|
fusePath: string;
|
|
11
13
|
}) => TOpenResult;
|
|
12
14
|
export { defaultFusePath, openFuseFd };
|
package/dist/lib/linux.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import nodeFs from "node:fs";
|
|
2
|
+
import { AT_FCWD, O_CLOEXEC } from "./constants.js";
|
|
3
|
+
/*import type { TSyscalls } from "./syscalls.ts";*/
|
|
2
4
|
|
|
3
5
|
/*type TOpenResult = {
|
|
4
6
|
error: Error;
|
|
@@ -10,20 +12,25 @@ import nodeFs from "node:fs";
|
|
|
10
12
|
|
|
11
13
|
const defaultFusePath = "/dev/fuse";
|
|
12
14
|
|
|
13
|
-
const openFuseFd = ({ fusePath }/*: { fusePath: string }*/)/*: TOpenResult*/ => {
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const openFuseFd = ({ syscalls, fusePath }/*: { syscalls: Pick<TSyscalls, "openat">; fusePath: string }*/)/*: TOpenResult*/ => {
|
|
16
|
+
const { errno, fd } = syscalls.openat({
|
|
17
|
+
dirFd: Number(AT_FCWD),
|
|
18
|
+
path: fusePath,
|
|
19
|
+
flags: nodeFs.constants.O_RDWR | nodeFs.constants.O_NONBLOCK | O_CLOEXEC,
|
|
20
|
+
mode: 0,
|
|
21
|
+
});
|
|
16
22
|
|
|
23
|
+
if (errno !== undefined) {
|
|
17
24
|
return {
|
|
18
|
-
error:
|
|
19
|
-
fuseFd,
|
|
20
|
-
};
|
|
21
|
-
} catch (err) {
|
|
22
|
-
return {
|
|
23
|
-
error: Error(`failed to open "${defaultFusePath}": ${err}`),
|
|
25
|
+
error: Error(`failed to open "${fusePath}": openat syscall failed with errno ${errno}`),
|
|
24
26
|
fuseFd: undefined,
|
|
25
27
|
};
|
|
26
28
|
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
error: undefined,
|
|
32
|
+
fuseFd: fd,
|
|
33
|
+
};
|
|
27
34
|
};
|
|
28
35
|
|
|
29
36
|
export {
|
package/dist/lib/message.js
CHANGED
|
@@ -132,6 +132,12 @@ const createMessageToKernelParser = () => {
|
|
|
132
132
|
|
|
133
133
|
const parseMessageToKernel = ({ data }/*: { data: Uint8Array }*/)/*: TParseMessageToKernelResult*/ => {
|
|
134
134
|
const outHeader = data.subarray(0, fuseOutHeaderParser.size);
|
|
135
|
+
if (outHeader.length < fuseOutHeaderParser.size) {
|
|
136
|
+
return {
|
|
137
|
+
error: Error(`invalid message: expected at least ${fuseOutHeaderParser.size} bytes for header, got ${outHeader.length} bytes`),
|
|
138
|
+
parsedMessageToKernel: undefined,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
135
141
|
|
|
136
142
|
const parsedOutHeader = fuseOutHeaderParser.parse({
|
|
137
143
|
data: outHeader
|
package/dist/lib/mount.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TSyscalls } from "./syscalls.js";
|
|
1
2
|
type TRequiredFuseMountOptions = {
|
|
2
3
|
rootmode: number;
|
|
3
4
|
user_id: number;
|
|
@@ -18,13 +19,15 @@ declare const mountAttributesToBitmask: ({ mountAttributes }: {
|
|
|
18
19
|
type TUnmountResult = {
|
|
19
20
|
error: Error | undefined;
|
|
20
21
|
};
|
|
21
|
-
declare const moveMount: ({ mountFd, newMountPoint, }: {
|
|
22
|
+
declare const moveMount: ({ syscalls, mountFd, newMountPoint, }: {
|
|
23
|
+
syscalls: Pick<TSyscalls, "move_mount">;
|
|
22
24
|
mountFd: number;
|
|
23
25
|
newMountPoint: string;
|
|
24
26
|
}) => {
|
|
25
27
|
error: any;
|
|
26
28
|
};
|
|
27
|
-
declare const unmount: ({ mountPoint, force, detach }: {
|
|
29
|
+
declare const unmount: ({ syscalls, mountPoint, force, detach, }: {
|
|
30
|
+
syscalls: Pick<TSyscalls, "umount">;
|
|
28
31
|
mountPoint: string;
|
|
29
32
|
force: boolean;
|
|
30
33
|
detach: boolean;
|
package/dist/lib/mount.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
MOUNT_ATTR_RDONLY,
|
|
9
9
|
MOVE_MOUNT_F_EMPTY_PATH
|
|
10
10
|
} from "./constants.js";
|
|
11
|
-
import {
|
|
11
|
+
/*import type { TSyscalls } from "./syscalls.ts";*/
|
|
12
12
|
|
|
13
13
|
/*type TRequiredFuseMountOptions = {
|
|
14
14
|
rootmode: number;
|
|
@@ -84,13 +84,15 @@ const MNT_DETACH = 2n;
|
|
|
84
84
|
|
|
85
85
|
// for now, only export this simple variant for use with fuse
|
|
86
86
|
const moveMount = ({
|
|
87
|
+
syscalls,
|
|
87
88
|
mountFd,
|
|
88
89
|
newMountPoint,
|
|
89
90
|
}/*: {
|
|
91
|
+
syscalls: Pick<TSyscalls, "move_mount">;
|
|
90
92
|
mountFd: number;
|
|
91
93
|
newMountPoint: string;
|
|
92
94
|
}*/) => {
|
|
93
|
-
const { errno: moveMountErrno } = move_mount({
|
|
95
|
+
const { errno: moveMountErrno } = syscalls.move_mount({
|
|
94
96
|
fromFd: mountFd,
|
|
95
97
|
fromPath: "",
|
|
96
98
|
toFd: Number(AT_FCWD),
|
|
@@ -109,7 +111,17 @@ const moveMount = ({
|
|
|
109
111
|
};
|
|
110
112
|
};
|
|
111
113
|
|
|
112
|
-
const unmount = ({
|
|
114
|
+
const unmount = ({
|
|
115
|
+
syscalls,
|
|
116
|
+
mountPoint,
|
|
117
|
+
force,
|
|
118
|
+
detach,
|
|
119
|
+
}/*: {
|
|
120
|
+
syscalls: Pick<TSyscalls, "umount">;
|
|
121
|
+
mountPoint: string;
|
|
122
|
+
force: boolean;
|
|
123
|
+
detach: boolean;
|
|
124
|
+
}*/)/*: TUnmountResult*/ => {
|
|
113
125
|
|
|
114
126
|
let flags = 0n;
|
|
115
127
|
|
|
@@ -121,7 +133,7 @@ const unmount = ({ mountPoint, force, detach }/*: { mountPoint: string, force: b
|
|
|
121
133
|
flags |= MNT_DETACH;
|
|
122
134
|
}
|
|
123
135
|
|
|
124
|
-
const { errno } = umount({
|
|
136
|
+
const { errno } = syscalls.umount({
|
|
125
137
|
target: mountPoint,
|
|
126
138
|
flags,
|
|
127
139
|
});
|
package/dist/lib/protocol.d.ts
CHANGED
|
@@ -892,6 +892,12 @@ type TGenericInterpretResult<T> = {
|
|
|
892
892
|
interpreted: T;
|
|
893
893
|
};
|
|
894
894
|
declare const createMessageFromKernelInterpreter: () => {
|
|
895
|
+
applyInitResult: ({ result }: {
|
|
896
|
+
result: Extract<TFuseResponse, {
|
|
897
|
+
forOpcode: "INIT";
|
|
898
|
+
errorCode: undefined;
|
|
899
|
+
}>["result"];
|
|
900
|
+
}) => void;
|
|
895
901
|
interpretMessageFromKernel: ({ parsedMessageFromKernel }: {
|
|
896
902
|
parsedMessageFromKernel: TParsedMessageFromKernel;
|
|
897
903
|
}) => TGenericInterpretResult<TFuseRequest>;
|