diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/std.zc | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/lib/std.zc b/src/lib/std.zc index 772b887..745a921 100644 --- a/src/lib/std.zc +++ b/src/lib/std.zc @@ -344,6 +344,24 @@ struct Num { // are its arguments. Host.raw fills it on each call. int rawblk[7]; +// an open file, from Host.open. its drop closes the descriptor, so the file is +// closed when its owner's block ends, when it is freed, or when the collector +// reclaims it (docs/SPEC.md 6.15). called as f.write(s), f.read(buf, n). +struct File { + int fd; + // writes a string. + // s: the text to write + // returns: how many bytes were written, negative on an error + int write(char* s) { return rt.syscall(rt.SYS_WRITE, this.fd, s, rt.len_w(s)); } + // reads bytes, one to a word. + // buf: where they go + // n: the most to read + // returns: how many were read, 0 at the end of the file, negative on an error + int read(char* buf, int n) { return rt.syscall(rt.SYS_READ, this.fd, buf, n); } + // the file dies: close its descriptor + void drop() { rt.syscall(rt.SYS_CLOSE, this.fd, 0, 0); } +} + // calls into the host that runs the vm: the environment, the clock, files and // raw system calls. called as std.Host.name(args). struct Host { @@ -373,17 +391,27 @@ struct Host { // returns: the time in seconds since 1970 static int now() { return rt.syscall(rt.SYS_TIME, 0, 0, 0); } + // opens a file. the result owns the descriptor: its drop closes it (see File). + // path: the file's name + // mode: 0 to read, 1 to write (the file is replaced, or created) + // returns: the open file, or null if it could not be opened + static File*.u open(char* path, int mode) { + int fd = rt.syscall(rt.SYS_OPEN, path, mode, 0); + if (fd < 0) return 0; + File* f = rt.new(File); + f.fd = fd; + return f; + } + // writes a string to a file, replacing what was there. the file is created if // it is missing. // path: the file's name // s: the text to write // returns: how many bytes were written, -1 if the file could not be opened static int writefile(char* path, char* s) { - int fd = rt.syscall(rt.SYS_OPEN, path, 1, 0), n; - if (fd < 0) return -1; - n = rt.syscall(rt.SYS_WRITE, fd, s, rt.len_w(s)); - rt.syscall(rt.SYS_CLOSE, fd, 0, 0); - return n; + File* f = Host.open(path, 1); + if (!f) return -1; + return f.write(s); // f's drop closes the file after the write } } |
