Files
jsrt/lib/stdlib/io.js
T
2026-10-26 12:39:58 +00:00

85 lines
2.6 KiB
JavaScript

// Files, with promises, on the IO natives (see lib/rt/io.h). They are like
// node's `fs.promises`, but only for UTF-8 text:
// - `fs.readFile(path)` gives the text of the file
// - `fs.writeFile(path, text)` makes or replaces the file
// A failure rejects with the negative errno, not an `Error`. A read or a write
// that the kernel does not finish in one op is not continued
import {
__native_io_queue_close,
__native_io_queue_open,
__native_io_queue_read,
__native_io_queue_stat,
__native_io_queue_write,
__native_io_result_number,
__native_io_result_string,
__native_io_status,
} from "jsrt:native";
import { __pending } from "jsrt:loop";
// A promise of what op `h` gives when it completes: its status, its data, or
// a number. A result can only be read before the next wait, so these read it
// when the op completes
function __io_status(h) {
return new Promise((resolve) => {
__pending[h] = (h) => resolve(__native_io_status(h));
});
}
function __io_string(h) {
return new Promise((resolve, reject) => {
__pending[h] = (h) => {
const status = __native_io_status(h);
if (status < 0) reject(status);
else resolve(__native_io_result_string(h));
};
});
}
function __io_number(h) {
return new Promise((resolve, reject) => {
__pending[h] = (h) => {
const status = __native_io_status(h);
if (status < 0) reject(status);
else resolve(__native_io_result_number(h));
};
});
}
// A promise of the status of op `h`, rejected if it failed
function __io_ok(h) {
return __io_status(h).then((status) => (status < 0 ? Promise.reject(status) : status));
}
export const fs = {
readFile(path) {
let fd = -1;
let text = "";
return __io_ok(__native_io_queue_open(path, 0, 0))
.then((f) => {
fd = f;
return __io_number(__native_io_queue_stat(path));
})
.then((size) => __io_string(__native_io_queue_read(fd, size, 0)))
.then((s) => {
text = s;
return __io_ok(__native_io_queue_close(fd));
})
.then(() => text);
},
writeFile(path, text) {
let fd = -1;
// O_WRONLY | O_CREAT | O_TRUNC, mode 0644
return __io_ok(__native_io_queue_open(path, 577, 420))
.then((f) => {
fd = f;
return __io_ok(__native_io_queue_write(fd, text, 0));
})
.then(() => __io_ok(__native_io_queue_close(fd)))
.then(() => undefined);
},
};