commit d6bffa900ca7098709078984f7a7e64dc8c0722d
parent 7ba16d2f5ee8cddb16e9a52c16e4b0bc4c2b6d78
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 4 Sep 2021 10:19:07 +0200
io::file: expand interface with fdalloc
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/io/+linux/file.ha b/io/+linux/file.ha
@@ -1,5 +1,6 @@
use errors;
use rt;
+use strings;
// This is an opaque type which encloses an OS-level file handle resource (on
// Unix, a file descriptor, or "fd") within a stream. It can be used as an
@@ -17,7 +18,7 @@ export type file = struct {
export fn fdopen(fd: int, name: str, mode: mode) file = {
let stream = file {
name = name,
- closer = &fd_close,
+ closer = &fd_close_static,
copier = &fd_copy,
seeker = &fd_seek,
fd = fd,
@@ -32,6 +33,14 @@ export fn fdopen(fd: int, name: str, mode: mode) file = {
return stream;
};
+// Similar to [[fdopen]], but heap-allocates the file. Closing the stream will
+// free the associated resources.
+export fn fdalloc(fd: int, name: str, mode: mode) *file = {
+ let file = alloc(fdopen(fd, strings::dup(name), mode));
+ file.closer = &fd_close;
+ return file;
+};
+
export fn is_file(s: *stream) bool = {
return s.reader == &fd_read
|| s.writer == &fd_write
@@ -62,11 +71,16 @@ fn fd_write(s: *stream, buf: const []u8) (size | error) = {
};
};
-fn fd_close(s: *stream) void = {
+fn fd_close_static(s: *stream) void = {
let stream = s: *file;
rt::close(stream.fd)!;
};
+fn fd_close(s: *stream) void = {
+ fd_close_static(s);
+ free(s);
+};
+
def SENDFILE_MAX: size = 2147479552z;
fn fd_copy(to: *stream, from: *stream) (size | error) = {