platform_file.ha (1992B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use errors; 5 use rt; 6 7 // This is an opaque type which encloses an OS-level file handle resource. It 8 // can be used as a [[handle]] in most situations, but there are some APIs which 9 // require a [[file]] with some OS-level handle backing it - this type is used 10 // for such APIs. 11 // 12 // On FreeBSD, [[file]] is a file descriptor. 13 export type file = int; 14 15 // Opens a Unix file descriptor as a file. This is a low-level interface, to 16 // open files most programs will use something like [[os::open]]. This function 17 // is not portable. 18 export fn fdopen(fd: int) file = fd; 19 20 fn fd_read(fd: file, buf: []u8) (size | EOF | error) = { 21 match (rt::read(fd, buf: *[*]u8, len(buf))) { 22 case let err: rt::errno => 23 return errors::errno(err); 24 case let n: size => 25 switch (n) { 26 case 0 => 27 return EOF; 28 case => 29 return n; 30 }; 31 }; 32 }; 33 34 fn fd_write(fd: file, buf: const []u8) (size | error) = { 35 match (rt::write(fd, buf: *const [*]u8, len(buf))) { 36 case let err: rt::errno => 37 return errors::errno(err); 38 case let n: size => 39 return n; 40 }; 41 }; 42 43 fn fd_close(fd: file) (void | error) = { 44 match (rt::close(fd)) { 45 case void => void; 46 case let err: rt::errno => 47 return errors::errno(err); 48 }; 49 }; 50 51 fn fd_seek( 52 fd: file, 53 offs: off, 54 whence: whence, 55 ) (off | error) = { 56 match (rt::lseek(fd, offs: i64, whence: int)) { 57 case let err: rt::errno => 58 return errors::errno(err); 59 case let n: i64 => 60 return n: off; 61 }; 62 }; 63 64 fn fd_copy(to: file, from: file) (size | error) = errors::unsupported; 65 66 fn fd_lock(fd: file, flags: int) (bool | error) = { 67 match (rt::flock(fd: int, flags)) { 68 case void => return true; 69 case let e: rt::errno => 70 if (e == rt::EWOULDBLOCK: rt::errno) { 71 return false; 72 } else { 73 return errors::errno(e); 74 }; 75 }; 76 }; 77 78 fn fd_trunc(fd: file, ln: size) (void | error) = { 79 match (rt::ftruncate(fd: int, ln: rt::off_t)) { 80 case void => void; 81 case let e: rt::errno => return errors::errno(e); 82 }; 83 };