lib/os: revert at enum to three top-level defs (post-#24)

cf24af8 fixed the negative-literal def DATA-emit gap that forced
the `at` enum bundle. Revert to Hare's shape: three export def
AT_FDCWD / AT_SYMLINK_NOFOLLOW / AT_EMPTY_PATH at i32, mirroring
ref/hare/sys/+linux/types.ha:45-51. Values from <linux/fcntl.h>:
-100 / 256 / 4096.

Four call sites (stat / lstat / fstat / exists) updated.
This commit is contained in:
2026-05-16 03:09:49 +09:00
parent cf24af8b26
commit 1aece29d53
7 changed files with 77 additions and 105 deletions

View File

@@ -390,16 +390,12 @@ export fn getenv(name: str) (str | void) = {
// but Hare's filestat doesn't expose btime either, so we stay on // but Hare's filestat doesn't expose btime either, so we stay on
// the simpler 144B kernel struct. // the simpler 144B kernel struct.
// at — flags for fstatat(2). Numeric values match <fcntl.h>. // fstatat(2) flag values. Linux constants from <linux/fcntl.h>.
// Bundled as an enum because top-level `def` of a negative literal // Names mirror Hare's ref/hare/sys/+linux/types.ha:45-51 (capital-
// (FDCWD = -100) doesn't get a DATA slot emitted by cstage cgen — // AT_ prefix, top-level `def`s).
// linker surfaces as "undefined reference". Tracked as task #24; export def AT_FDCWD: i32 = -100;
// enum-member resolution sidesteps it cleanly. export def AT_SYMLINK_NOFOLLOW: i32 = 256; // 0x100
type at = enum i64 { export def AT_EMPTY_PATH: i32 = 4096; // 0x1000
FDCWD = -100,
SYMLINK_NOFOLLOW = 256, // 0x100
EMPTY_PATH = 4096, // 0x1000
};
// mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/ // mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/
// types.ha:63). Permission bits are the standard Unix octal subset; // types.ha:63). Permission bits are the standard Unix octal subset;
@@ -558,7 +554,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = {
export fn stat(out: *filestat, path: *u8) (void | oserror) = { export fn stat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -568,8 +564,8 @@ export fn stat(out: *filestat, path: *u8) (void | oserror) = {
export fn lstat(out: *filestat, path: *u8) (void | oserror) = { export fn lstat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, AT_FDCWD: i64, path: i64, (&k): i64,
at.SYMLINK_NOFOLLOW: i64); AT_SYMLINK_NOFOLLOW: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -581,7 +577,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
fd: i64, (&emptypath[0]): i64, (&k): i64, fd: i64, (&emptypath[0]): i64, (&k): i64,
at.EMPTY_PATH: i64); AT_EMPTY_PATH: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -605,6 +601,6 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
export fn exists(path: *u8) bool = { export fn exists(path: *u8) bool = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
return r >= 0i64; return r >= 0i64;
}; };

View File

@@ -391,16 +391,12 @@ export fn getenv(name: str) (str | void) = {
// but Hare's filestat doesn't expose btime either, so we stay on // but Hare's filestat doesn't expose btime either, so we stay on
// the simpler 144B kernel struct. // the simpler 144B kernel struct.
// at — flags for fstatat(2). Numeric values match <fcntl.h>. // fstatat(2) flag values. Linux constants from <linux/fcntl.h>.
// Bundled as an enum because top-level `def` of a negative literal // Names mirror Hare's ref/hare/sys/+linux/types.ha:45-51 (capital-
// (FDCWD = -100) doesn't get a DATA slot emitted by cstage cgen — // AT_ prefix, top-level `def`s).
// linker surfaces as "undefined reference". Tracked as task #24; export def AT_FDCWD: i32 = -100;
// enum-member resolution sidesteps it cleanly. export def AT_SYMLINK_NOFOLLOW: i32 = 256; // 0x100
type at = enum i64 { export def AT_EMPTY_PATH: i32 = 4096; // 0x1000
FDCWD = -100,
SYMLINK_NOFOLLOW = 256, // 0x100
EMPTY_PATH = 4096, // 0x1000
};
// mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/ // mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/
// types.ha:63). Permission bits are the standard Unix octal subset; // types.ha:63). Permission bits are the standard Unix octal subset;
@@ -559,7 +555,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = {
export fn stat(out: *filestat, path: *u8) (void | oserror) = { export fn stat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -569,8 +565,8 @@ export fn stat(out: *filestat, path: *u8) (void | oserror) = {
export fn lstat(out: *filestat, path: *u8) (void | oserror) = { export fn lstat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, AT_FDCWD: i64, path: i64, (&k): i64,
at.SYMLINK_NOFOLLOW: i64); AT_SYMLINK_NOFOLLOW: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -582,7 +578,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
fd: i64, (&emptypath[0]): i64, (&k): i64, fd: i64, (&emptypath[0]): i64, (&k): i64,
at.EMPTY_PATH: i64); AT_EMPTY_PATH: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -606,7 +602,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
export fn exists(path: *u8) bool = { export fn exists(path: *u8) bool = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
return r >= 0i64; return r >= 0i64;
}; };

View File

@@ -391,16 +391,12 @@ export fn getenv(name: str) (str | void) = {
// but Hare's filestat doesn't expose btime either, so we stay on // but Hare's filestat doesn't expose btime either, so we stay on
// the simpler 144B kernel struct. // the simpler 144B kernel struct.
// at — flags for fstatat(2). Numeric values match <fcntl.h>. // fstatat(2) flag values. Linux constants from <linux/fcntl.h>.
// Bundled as an enum because top-level `def` of a negative literal // Names mirror Hare's ref/hare/sys/+linux/types.ha:45-51 (capital-
// (FDCWD = -100) doesn't get a DATA slot emitted by cstage cgen — // AT_ prefix, top-level `def`s).
// linker surfaces as "undefined reference". Tracked as task #24; export def AT_FDCWD: i32 = -100;
// enum-member resolution sidesteps it cleanly. export def AT_SYMLINK_NOFOLLOW: i32 = 256; // 0x100
type at = enum i64 { export def AT_EMPTY_PATH: i32 = 4096; // 0x1000
FDCWD = -100,
SYMLINK_NOFOLLOW = 256, // 0x100
EMPTY_PATH = 4096, // 0x1000
};
// mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/ // mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/
// types.ha:63). Permission bits are the standard Unix octal subset; // types.ha:63). Permission bits are the standard Unix octal subset;
@@ -559,7 +555,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = {
export fn stat(out: *filestat, path: *u8) (void | oserror) = { export fn stat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -569,8 +565,8 @@ export fn stat(out: *filestat, path: *u8) (void | oserror) = {
export fn lstat(out: *filestat, path: *u8) (void | oserror) = { export fn lstat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, AT_FDCWD: i64, path: i64, (&k): i64,
at.SYMLINK_NOFOLLOW: i64); AT_SYMLINK_NOFOLLOW: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -582,7 +578,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
fd: i64, (&emptypath[0]): i64, (&k): i64, fd: i64, (&emptypath[0]): i64, (&k): i64,
at.EMPTY_PATH: i64); AT_EMPTY_PATH: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -606,7 +602,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
export fn exists(path: *u8) bool = { export fn exists(path: *u8) bool = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
return r >= 0i64; return r >= 0i64;
}; };

View File

@@ -391,16 +391,12 @@ export fn getenv(name: str) (str | void) = {
// but Hare's filestat doesn't expose btime either, so we stay on // but Hare's filestat doesn't expose btime either, so we stay on
// the simpler 144B kernel struct. // the simpler 144B kernel struct.
// at — flags for fstatat(2). Numeric values match <fcntl.h>. // fstatat(2) flag values. Linux constants from <linux/fcntl.h>.
// Bundled as an enum because top-level `def` of a negative literal // Names mirror Hare's ref/hare/sys/+linux/types.ha:45-51 (capital-
// (FDCWD = -100) doesn't get a DATA slot emitted by cstage cgen — // AT_ prefix, top-level `def`s).
// linker surfaces as "undefined reference". Tracked as task #24; export def AT_FDCWD: i32 = -100;
// enum-member resolution sidesteps it cleanly. export def AT_SYMLINK_NOFOLLOW: i32 = 256; // 0x100
type at = enum i64 { export def AT_EMPTY_PATH: i32 = 4096; // 0x1000
FDCWD = -100,
SYMLINK_NOFOLLOW = 256, // 0x100
EMPTY_PATH = 4096, // 0x1000
};
// mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/ // mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/
// types.ha:63). Permission bits are the standard Unix octal subset; // types.ha:63). Permission bits are the standard Unix octal subset;
@@ -559,7 +555,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = {
export fn stat(out: *filestat, path: *u8) (void | oserror) = { export fn stat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -569,8 +565,8 @@ export fn stat(out: *filestat, path: *u8) (void | oserror) = {
export fn lstat(out: *filestat, path: *u8) (void | oserror) = { export fn lstat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, AT_FDCWD: i64, path: i64, (&k): i64,
at.SYMLINK_NOFOLLOW: i64); AT_SYMLINK_NOFOLLOW: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -582,7 +578,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
fd: i64, (&emptypath[0]): i64, (&k): i64, fd: i64, (&emptypath[0]): i64, (&k): i64,
at.EMPTY_PATH: i64); AT_EMPTY_PATH: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -606,7 +602,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
export fn exists(path: *u8) bool = { export fn exists(path: *u8) bool = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
return r >= 0i64; return r >= 0i64;
}; };

View File

@@ -391,16 +391,12 @@ export fn getenv(name: str) (str | void) = {
// but Hare's filestat doesn't expose btime either, so we stay on // but Hare's filestat doesn't expose btime either, so we stay on
// the simpler 144B kernel struct. // the simpler 144B kernel struct.
// at — flags for fstatat(2). Numeric values match <fcntl.h>. // fstatat(2) flag values. Linux constants from <linux/fcntl.h>.
// Bundled as an enum because top-level `def` of a negative literal // Names mirror Hare's ref/hare/sys/+linux/types.ha:45-51 (capital-
// (FDCWD = -100) doesn't get a DATA slot emitted by cstage cgen — // AT_ prefix, top-level `def`s).
// linker surfaces as "undefined reference". Tracked as task #24; export def AT_FDCWD: i32 = -100;
// enum-member resolution sidesteps it cleanly. export def AT_SYMLINK_NOFOLLOW: i32 = 256; // 0x100
type at = enum i64 { export def AT_EMPTY_PATH: i32 = 4096; // 0x1000
FDCWD = -100,
SYMLINK_NOFOLLOW = 256, // 0x100
EMPTY_PATH = 4096, // 0x1000
};
// mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/ // mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/
// types.ha:63). Permission bits are the standard Unix octal subset; // types.ha:63). Permission bits are the standard Unix octal subset;
@@ -559,7 +555,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = {
export fn stat(out: *filestat, path: *u8) (void | oserror) = { export fn stat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -569,8 +565,8 @@ export fn stat(out: *filestat, path: *u8) (void | oserror) = {
export fn lstat(out: *filestat, path: *u8) (void | oserror) = { export fn lstat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, AT_FDCWD: i64, path: i64, (&k): i64,
at.SYMLINK_NOFOLLOW: i64); AT_SYMLINK_NOFOLLOW: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -582,7 +578,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
fd: i64, (&emptypath[0]): i64, (&k): i64, fd: i64, (&emptypath[0]): i64, (&k): i64,
at.EMPTY_PATH: i64); AT_EMPTY_PATH: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -606,7 +602,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
export fn exists(path: *u8) bool = { export fn exists(path: *u8) bool = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
return r >= 0i64; return r >= 0i64;
}; };

View File

@@ -391,16 +391,12 @@ export fn getenv(name: str) (str | void) = {
// but Hare's filestat doesn't expose btime either, so we stay on // but Hare's filestat doesn't expose btime either, so we stay on
// the simpler 144B kernel struct. // the simpler 144B kernel struct.
// at — flags for fstatat(2). Numeric values match <fcntl.h>. // fstatat(2) flag values. Linux constants from <linux/fcntl.h>.
// Bundled as an enum because top-level `def` of a negative literal // Names mirror Hare's ref/hare/sys/+linux/types.ha:45-51 (capital-
// (FDCWD = -100) doesn't get a DATA slot emitted by cstage cgen — // AT_ prefix, top-level `def`s).
// linker surfaces as "undefined reference". Tracked as task #24; export def AT_FDCWD: i32 = -100;
// enum-member resolution sidesteps it cleanly. export def AT_SYMLINK_NOFOLLOW: i32 = 256; // 0x100
type at = enum i64 { export def AT_EMPTY_PATH: i32 = 4096; // 0x1000
FDCWD = -100,
SYMLINK_NOFOLLOW = 256, // 0x100
EMPTY_PATH = 4096, // 0x1000
};
// mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/ // mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/
// types.ha:63). Permission bits are the standard Unix octal subset; // types.ha:63). Permission bits are the standard Unix octal subset;
@@ -559,7 +555,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = {
export fn stat(out: *filestat, path: *u8) (void | oserror) = { export fn stat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -569,8 +565,8 @@ export fn stat(out: *filestat, path: *u8) (void | oserror) = {
export fn lstat(out: *filestat, path: *u8) (void | oserror) = { export fn lstat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, AT_FDCWD: i64, path: i64, (&k): i64,
at.SYMLINK_NOFOLLOW: i64); AT_SYMLINK_NOFOLLOW: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -582,7 +578,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
fd: i64, (&emptypath[0]): i64, (&k): i64, fd: i64, (&emptypath[0]): i64, (&k): i64,
at.EMPTY_PATH: i64); AT_EMPTY_PATH: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -606,7 +602,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
export fn exists(path: *u8) bool = { export fn exists(path: *u8) bool = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
return r >= 0i64; return r >= 0i64;
}; };

View File

@@ -391,16 +391,12 @@ export fn getenv(name: str) (str | void) = {
// but Hare's filestat doesn't expose btime either, so we stay on // but Hare's filestat doesn't expose btime either, so we stay on
// the simpler 144B kernel struct. // the simpler 144B kernel struct.
// at — flags for fstatat(2). Numeric values match <fcntl.h>. // fstatat(2) flag values. Linux constants from <linux/fcntl.h>.
// Bundled as an enum because top-level `def` of a negative literal // Names mirror Hare's ref/hare/sys/+linux/types.ha:45-51 (capital-
// (FDCWD = -100) doesn't get a DATA slot emitted by cstage cgen — // AT_ prefix, top-level `def`s).
// linker surfaces as "undefined reference". Tracked as task #24; export def AT_FDCWD: i32 = -100;
// enum-member resolution sidesteps it cleanly. export def AT_SYMLINK_NOFOLLOW: i32 = 256; // 0x100
type at = enum i64 { export def AT_EMPTY_PATH: i32 = 4096; // 0x1000
FDCWD = -100,
SYMLINK_NOFOLLOW = 256, // 0x100
EMPTY_PATH = 4096, // 0x1000
};
// mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/ // mode — file-mode bits. Mirrors Hare's fs::mode (ref/hare/fs/
// types.ha:63). Permission bits are the standard Unix octal subset; // types.ha:63). Permission bits are the standard Unix octal subset;
@@ -559,7 +555,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = {
export fn stat(out: *filestat, path: *u8) (void | oserror) = { export fn stat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -569,8 +565,8 @@ export fn stat(out: *filestat, path: *u8) (void | oserror) = {
export fn lstat(out: *filestat, path: *u8) (void | oserror) = { export fn lstat(out: *filestat, path: *u8) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, AT_FDCWD: i64, path: i64, (&k): i64,
at.SYMLINK_NOFOLLOW: i64); AT_SYMLINK_NOFOLLOW: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -582,7 +578,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
fd: i64, (&emptypath[0]): i64, (&k): i64, fd: i64, (&emptypath[0]): i64, (&k): i64,
at.EMPTY_PATH: i64); AT_EMPTY_PATH: i64);
if (r < 0) { return r: oserror; }; if (r < 0) { return r: oserror; };
fillfilestat(out, &k); fillfilestat(out, &k);
}; };
@@ -606,7 +602,7 @@ export fn fstat(out: *filestat, fd: i32) (void | oserror) = {
export fn exists(path: *u8) bool = { export fn exists(path: *u8) bool = {
let k: kstat; let k: kstat;
let r: i64 = syscall4(nr.NEWFSTATAT, let r: i64 = syscall4(nr.NEWFSTATAT,
at.FDCWD: i64, path: i64, (&k): i64, 0i64); AT_FDCWD: i64, path: i64, (&k): i64, 0i64);
return r >= 0i64; return r >= 0i64;
}; };