hare

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

commit 5cdb439923a9f00cb0efc994dd55ab914194a2fa
parent 1749a9a0ebc46a4cfad00791fca871ce48af8873
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon,  8 Feb 2021 15:31:09 -0500

os::exec: check for X_OK when testing executable

Diffstat:
Mos/exec/+linux.ha | 6++++++
Mrt/+linux/syscallno+aarch64.ha | 1+
Mrt/+linux/syscallno+x86_64.ha | 1+
Mrt/+linux/syscalls.ha | 22++++++++++++++++++++++
Mrt/+linux/types.ha | 5+++++
5 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/os/exec/+linux.ha b/os/exec/+linux.ha @@ -31,6 +31,12 @@ fn errno_to_os(err: rt::errno) os_error = { }; fn open(path: str) (platform | os_error) = { + match (rt::access(path, rt::X_OK)) { + err: rt::errno => errno_to_os(err), + b: bool => if (!b) { + return errno_to_os(rt::EACCES); + }, + }; return match (rt::open(path: *const char, rt::O_RDONLY, 0u)) { fd: int => fd, err: rt::errno => errno_to_os(err), diff --git a/rt/+linux/syscallno+aarch64.ha b/rt/+linux/syscallno+aarch64.ha @@ -289,3 +289,4 @@ export def SYS_fsmount: u64 = 432u64; export def SYS_fspick: u64 = 433u64; export def SYS_pidfd_open: u64 = 434u64; export def SYS_clone3: u64 = 435u64; +export def SYS_faccessat2: u64 = 439u64; diff --git a/rt/+linux/syscallno+x86_64.ha b/rt/+linux/syscallno+x86_64.ha @@ -343,3 +343,4 @@ export def SYS_fsopen: u64 = 430u64; export def SYS_fsconfig: u64 = 431u64; export def SYS_fsmount: u64 = 432u64; export def SYS_fspick: u64 = 433u64; +export def SYS_faccessat2: u64 = 439u64; diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha @@ -131,3 +131,25 @@ export fn lseek(fd: int, off: i64, whence: uint) (i64 | errno) = { n: u64 => n: i64, }; }; + +export fn faccessat( + dirfd: int, + path: *const char, + mode: int, + flags: int, +) (bool | errno) = { + return match (wrap_return(syscall4(SYS_faccessat2, dirfd: u64, + path: uintptr: u64, mode: u64, flags: u64))) { + err: errno => switch (err) { + EACCES => false, + * => err, + }, + n: u64 => { + assert(n == 0u64); + true; + }, + }; +}; + +export fn access(path: *const char, mode: int) (bool | errno) = + faccessat(AT_FDCWD, path, mode, 0); diff --git a/rt/+linux/types.ha b/rt/+linux/types.ha @@ -170,3 +170,8 @@ 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 def F_OK: int = 0; +export def R_OK: int = 4; +export def W_OK: int = 2; +export def X_OK: int = 1;