hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 72cbcd3a31b00414f9e5285e70c85149b6ff8925
parent fcdbc7b4c2d76638fb33772f4756c7231a40b8f5
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun,  7 Feb 2021 10:07:48 -0500

rt: add stat wrapper

Diffstat:
Art/+linux/arch+aarch64.ha | 18++++++++++++++++++
Art/+linux/arch+x86_64.ha | 17+++++++++++++++++
Mrt/+linux/errno.ha | 4++--
Art/+linux/stat.ha | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrt/+linux/syscalls.ha | 74--------------------------------------------------------------------------
Art/+linux/types.ha | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 239 insertions(+), 76 deletions(-)

diff --git a/rt/+linux/arch+aarch64.ha b/rt/+linux/arch+aarch64.ha @@ -0,0 +1,18 @@ +export type st = struct { + dev: dev_t, + ino: ino_t, + mode: mode_t, + nlink: nlink_t, + uid: uid_t, + gid: gid_t, + rdev: dev_t, + __pad0: u64, + sz: i64, + blksz: i64, + __pad1: int, + blocks: i64, + atime: timespec, + mtime: timespec, + ctime: timespec, + __pad2: [2]uint, +}; diff --git a/rt/+linux/arch+x86_64.ha b/rt/+linux/arch+x86_64.ha @@ -0,0 +1,17 @@ +export type st = struct { + dev: dev_t, + ino: ino_t, + nlink: nlink_t, + mode: mode_t, + uid: uid_t, + gid: gid_t, + __pad0: uint, + rdev: dev_t, + sz: i64, + blksz: i64, + blocks: i64, + atime: timespec, + mtime: timespec, + ctime: timespec, + __pad1: [3]i64, +}; diff --git a/rt/+linux/errno.ha b/rt/+linux/errno.ha @@ -6,8 +6,8 @@ export fn wrap_errno(err: int) errno = err: errno; // Checks the return value from a Linux syscall and, if found to be in error, // returns the appropriate error. Otherwise, returns the original value. -export fn wrap_return(r: size) (errno | size) = { - if (r > -4096z) { +export fn wrap_return(r: u64) (errno | size) = { + if (r > -4096u64) { return (-(r: i64)): int: errno; }; return r; diff --git a/rt/+linux/stat.ha b/rt/+linux/stat.ha @@ -0,0 +1,57 @@ +fn mkdev(major: u32, minor: u32) dev_t = + ((major: u64 & 0xFFFFF000u64) << 32u64) | + ((major: u64 & 0x00000FFFu64) << 8u64) | + ((minor: u64 & 0xFFFFFF00u64) << 12u64) | + (minor: u64 & 0x000000FFu64); + +fn fstatat_statx( + dirfd: int, + path: *const char, + flags: int, + mask: uint, + statbuf: *stx, +) (void | errno) = match (wrap_return(syscall5( + SYS_statx, dirfd: u64, path: uintptr: u64, flags: u64, + mask: u64, statbuf: uintptr: u64))) { + err: errno => err, + size => void, +}; + +export fn fstatat( + dirfd: int, + path: *const char, + statbuf: *st, + flags: int, +) (errno | void) = { + let statxbuf = stx { ... }; + match (fstatat_statx(dirfd, path, flags, STATX_BASIC_STATS, &statxbuf)) { + err: errno => return err, + void => void, + }; + statbuf.dev = mkdev(statxbuf.dev_major, statxbuf.dev_minor); + statbuf.ino = statxbuf.ino; + statbuf.mode = statxbuf.mode; + statbuf.nlink = statxbuf.nlink; + statbuf.uid = statxbuf.uid; + statbuf.gid = statxbuf.gid; + statbuf.rdev = mkdev(statxbuf.dev_major, statxbuf.dev_minor); + statbuf.sz = statxbuf.sz: i64; + statbuf.blksz = statxbuf.blksize: i64; + statbuf.blocks = statxbuf.blocks: i64; + statbuf.atime.tv_sec = statxbuf.atime.tv_sec; + statbuf.atime.tv_nsec = statxbuf.atime.tv_nsec: i64; + statbuf.mtime.tv_sec = statxbuf.mtime.tv_sec; + statbuf.mtime.tv_nsec = statxbuf.mtime.tv_nsec: i64; + statbuf.ctime.tv_sec = statxbuf.ctime.tv_sec; + statbuf.ctime.tv_nsec = statxbuf.ctime.tv_nsec: i64; + return void; +}; + +export fn stat(path: *const char, statbuf: *st) (errno | void) = + fstatat(AT_FDCWD, path, statbuf, 0); + +export fn fstat(fd: int, statbuf: *st) (errno | void) = + fstatat(fd, "", statbuf, AT_EMPTY_PATH); + +export fn lstat(path: *const char, statbuf: *st) (errno | void) = + fstatat(AT_FDCWD, path, statbuf, AT_SYMLINK_NOFOLLOW); diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha @@ -17,8 +17,6 @@ export fn open(path: *const char, flags: int, mode: uint) size = { path: uintptr: u64, flags: u64, mode: u64): size; }; -export def AT_FDCWD: int = -100; - export fn close(fd: int) int = syscall1(SYS_close, fd: u64): int; export fn getpid() int = syscall0(SYS_getpid): int; @@ -31,78 +29,6 @@ export @noreturn fn exit(status: int) void = syscall1(SYS_exit, status: u64); export fn kill(pid: int, signal: int) int = syscall2(SYS_kill, pid: u64, signal: u64): int; -export def SIGHUP: int = 1; -export def SIGINT: int = 2; -export def SIGQUIT: int = 3; -export def SIGILL: int = 4; -export def SIGTRAP: int = 5; -export def SIGABRT: int = 6; -export def SIGBUS: int = 7; -export def SIGFPE: int = 8; -export def SIGKILL: int = 9; -export def SIGUSR1: int = 10; -export def SIGSEGV: int = 11; -export def SIGUSR2: int = 12; -export def SIGPIPE: int = 13; -export def SIGALRM: int = 14; -export def SIGTERM: int = 15; -export def SIGSTKFLT: int = 16; -export def SIGCHLD: int = 17; -export def SIGCONT: int = 18; -export def SIGSTOP: int = 19; -export def SIGTSTP: int = 20; -export def SIGTTIN: int = 21; -export def SIGTTOU: int = 22; -export def SIGURG: int = 23; -export def SIGXCPU: int = 24; -export def SIGXFSZ: int = 25; -export def SIGVTALRM: int = 26; -export def SIGPROF: int = 27; -export def SIGWINCH: int = 28; -export def SIGIO: int = 29; -export def SIGPOLL: int = 29; -export def SIGPWR: int = 30; -export def SIGSYS: int = 31; - -export def MAP_SHARED: uint = 0x01u; -export def MAP_PRIVATE: uint = 0x02u; -export def MAP_SHARED_VALIDATE: uint = 0x03u; -export def MAP_FIXED: uint = 0x10u; -export def MAP_ANON: uint = 0x20u; -export def MAP_NORESERVE: uint = 0x4000u; -export def MAP_GROWSDOWN: uint = 0x0100u; -export def MAP_DENYWRITE: uint = 0x0800u; -export def MAP_EXECUTABLE: uint = 0x1000u; -export def MAP_LOCKED: uint = 0x2000u; -export def MAP_POPULATE: uint = 0x8000u; -export def MAP_NONBLOCK: uint = 0x10000u; -export def MAP_STACK: uint = 0x20000u; -export def MAP_HUGETLB: uint = 0x40000u; -export def MAP_SYNC: uint = 0x80000u; -export def MAP_FIXED_NOREPLACE: uint = 0x100000u; -export def MAP_FILE: uint = 0u; -export def MAP_HUGE_SHIFT: uint = 26u; -export def MAP_HUGE_MASK: uint = 0x3fu; -export def MAP_HUGE_64KB: uint = 16u << 26u; -export def MAP_HUGE_512KB: uint = 19u << 26u; -export def MAP_HUGE_1MB: uint = 20u << 26u; -export def MAP_HUGE_2MB: uint = 21u << 26u; -export def MAP_HUGE_8MB: uint = 23u << 26u; -export def MAP_HUGE_16MB: uint = 24u << 26u; -export def MAP_HUGE_32MB: uint = 25u << 26u; -export def MAP_HUGE_256MB: uint = 28u << 26u; -export def MAP_HUGE_512MB: uint = 29u << 26u; -export def MAP_HUGE_1GB: uint = 30u << 26u; -export def MAP_HUGE_2GB: uint = 31u << 26u; -export def MAP_HUGE_16GB: uint = 34u << 26u; - -export def PROT_NONE: uint = 0u; -export def PROT_READ: uint = 1u; -export def PROT_WRITE: uint = 2u; -export def PROT_EXEC: uint = 4u; -export def PROT_GROWSDOWN: uint = 0x01000000u; -export def PROT_GROWSUP: uint = 0x02000000u; - export fn mmap( addr: nullable *void, length: size, diff --git a/rt/+linux/types.ha b/rt/+linux/types.ha @@ -0,0 +1,145 @@ +export type dev_t = u64; +export type ino_t = u64; +export type nlink_t = u64; +export type mode_t = uint; +export type uid_t = uint; +export type gid_t = uint; +export type time_t = i64; +export type suseconds_t = i64; + +export type timeval = struct { + tv_sec: time_t, + tv_usec: suseconds_t, +}; + +export type timespec = struct { + tv_sec: time_t, + tv_nsec: i64, +}; + +export def AT_FDCWD: int = -100; +export def AT_SYMLINK_NOFOLLOW: int = 0x100; +export def AT_REMOVEDIR: int = 0x200; +export def AT_SYMLINK_FOLLOW: int = 0x400; +export def AT_EACCESS: int = 0x200; +export def AT_NO_AUTOMOUNT: int = 0x800; +export def AT_EMPTY_PATH: int = 0x1000; +export def AT_STATX_SYNC_TYPE: int = 0x6000; +export def AT_STATX_SYNC_AS_STAT: int = 0x0000; +export def AT_STATX_FORCE_SYNC: int = 0x2000; +export def AT_STATX_DONT_SYNC: int = 0x4000; +export def AT_RECURSIVE: int = 0x8000; + +type statx_timestamp = struct { + tv_sec: i64, + tv_nsec: u32, +}; + +type stx = struct { + mask: u32, + blksize: u32, + attributes: u64, + nlink: u32, + uid: u32, + gid: u32, + mode: u16, + ino: u64, + sz: u64, + blocks: u64, + attr_mask: u64, + atime: statx_timestamp, + btime: statx_timestamp, + ctime: statx_timestamp, + mtime: statx_timestamp, + rdev_major: u32, + rdev_minor: u32, + dev_major: u32, + dev_minor: u32, +}; + +def STATX_TYPE: uint = 0x00000001u; +def STATX_MODE: uint = 0x00000002u; +def STATX_NLINK: uint = 0x00000004u; +def STATX_UID: uint = 0x00000008u; +def STATX_GID: uint = 0x00000010u; +def STATX_ATIME: uint = 0x00000020u; +def STATX_MTIME: uint = 0x00000040u; +def STATX_CTIME: uint = 0x00000080u; +def STATX_INO: uint = 0x00000100u; +def STATX_SIZE: uint = 0x00000200u; +def STATX_BLOCKS: uint = 0x00000400u; +def STATX_BASIC_STATS: uint = 0x000007FFu; +def STATX_BTIME: uint = 0x00000800u; +def STATX_MNT_ID: uint = 0x00001000u; + +export def SIGHUP: int = 1; +export def SIGINT: int = 2; +export def SIGQUIT: int = 3; +export def SIGILL: int = 4; +export def SIGTRAP: int = 5; +export def SIGABRT: int = 6; +export def SIGBUS: int = 7; +export def SIGFPE: int = 8; +export def SIGKILL: int = 9; +export def SIGUSR1: int = 10; +export def SIGSEGV: int = 11; +export def SIGUSR2: int = 12; +export def SIGPIPE: int = 13; +export def SIGALRM: int = 14; +export def SIGTERM: int = 15; +export def SIGSTKFLT: int = 16; +export def SIGCHLD: int = 17; +export def SIGCONT: int = 18; +export def SIGSTOP: int = 19; +export def SIGTSTP: int = 20; +export def SIGTTIN: int = 21; +export def SIGTTOU: int = 22; +export def SIGURG: int = 23; +export def SIGXCPU: int = 24; +export def SIGXFSZ: int = 25; +export def SIGVTALRM: int = 26; +export def SIGPROF: int = 27; +export def SIGWINCH: int = 28; +export def SIGIO: int = 29; +export def SIGPOLL: int = 29; +export def SIGPWR: int = 30; +export def SIGSYS: int = 31; + +export def MAP_SHARED: uint = 0x01u; +export def MAP_PRIVATE: uint = 0x02u; +export def MAP_SHARED_VALIDATE: uint = 0x03u; +export def MAP_FIXED: uint = 0x10u; +export def MAP_ANON: uint = 0x20u; +export def MAP_NORESERVE: uint = 0x4000u; +export def MAP_GROWSDOWN: uint = 0x0100u; +export def MAP_DENYWRITE: uint = 0x0800u; +export def MAP_EXECUTABLE: uint = 0x1000u; +export def MAP_LOCKED: uint = 0x2000u; +export def MAP_POPULATE: uint = 0x8000u; +export def MAP_NONBLOCK: uint = 0x10000u; +export def MAP_STACK: uint = 0x20000u; +export def MAP_HUGETLB: uint = 0x40000u; +export def MAP_SYNC: uint = 0x80000u; +export def MAP_FIXED_NOREPLACE: uint = 0x100000u; +export def MAP_FILE: uint = 0u; +export def MAP_HUGE_SHIFT: uint = 26u; +export def MAP_HUGE_MASK: uint = 0x3fu; +export def MAP_HUGE_64KB: uint = 16u << 26u; +export def MAP_HUGE_512KB: uint = 19u << 26u; +export def MAP_HUGE_1MB: uint = 20u << 26u; +export def MAP_HUGE_2MB: uint = 21u << 26u; +export def MAP_HUGE_8MB: uint = 23u << 26u; +export def MAP_HUGE_16MB: uint = 24u << 26u; +export def MAP_HUGE_32MB: uint = 25u << 26u; +export def MAP_HUGE_256MB: uint = 28u << 26u; +export def MAP_HUGE_512MB: uint = 29u << 26u; +export def MAP_HUGE_1GB: uint = 30u << 26u; +export def MAP_HUGE_2GB: uint = 31u << 26u; +export def MAP_HUGE_16GB: uint = 34u << 26u; + +export def PROT_NONE: uint = 0u; +export def PROT_READ: uint = 1u; +export def PROT_WRITE: uint = 2u; +export def PROT_EXEC: uint = 4u; +export def PROT_GROWSDOWN: uint = 0x01000000u; +export def PROT_GROWSUP: uint = 0x02000000u;