commit 523d52ea909f59a662b64b79e168d0dd5c390cc9
parent c69716e86461c93f9069b779c4eed9d7cd2b60f4
Author: Simon Ser <contact@emersion.fr>
Date: Fri, 27 May 2022 14:36:10 +0000
dirs/xdg: add runtime
This parses XDG_RUNTIME_DIR and performs the required sanity checks.
Signed-off-by: Simon Ser <contact@emersion.fr>
Diffstat:
3 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/dirs/xdg.ha b/dirs/xdg.ha
@@ -3,11 +3,14 @@
// (c) 2021 Eyal Sawady <ecs@d2evs.net>
// (c) 2022 Sebastian <sebastian@sebsite.pw>
// (c) 2022 Jon Eskin <eskinjp@gmail.com>
+// (c) 2022 Simon Ser <contact@emersion.fr>
+use errors;
use fmt;
use fs;
use os;
use path;
use io;
+use unix;
fn lookup(prog: str, var: str, default: str) str = {
static let buf = path::buffer { ... };
@@ -87,3 +90,32 @@ export fn state(prog: str) str = {
// Returns an [[fs::fs]] for storing program state data.
export fn statefs(prog: str) *fs::fs = os::diropen(state(prog)) as *fs::fs;
+
+// Returns a directory suitable for storing non-essential runtime files and
+// other file objects (such as sockets, named pipes, and so on). Applications
+// should use this directory for communication and synchronization purposes and
+// should not place larger files in it, since it might reside in runtime memory
+// and cannot necessarily be swapped out to disk.
+//
+// The specification requires the directory to be owned by the current user and
+// not be world-readable. No fallback is implemented in case XDG_RUNTIME_DIR is
+// unset or incorrectly set up.
+export fn runtime() (str | fs::error) = {
+ let path = match (os::getenv("XDG_RUNTIME_DIR")) {
+ case let path: str =>
+ yield path;
+ case void =>
+ return errors::noentry;
+ };
+
+ const st = os::stat(path)?;
+ const uid = unix::getuid();
+ if (st.uid != uid || fs::mode_perm(st.mode) != fs::mode::USER_RWX) {
+ return errors::noaccess;
+ };
+ if (!fs::isdir(st.mode)) {
+ return fs::wrongtype;
+ };
+
+ return path;
+};
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -494,7 +494,7 @@ crypto_x25519() {
dirs() {
gen_srcs dirs \
xdg.ha
- gen_ssa dirs fs io os path fmt
+ gen_ssa dirs fs io os path fmt unix
}
encoding_base64() {
diff --git a/stdlib.mk b/stdlib.mk
@@ -1035,7 +1035,7 @@ $(HARECACHE)/datetime/datetime-freebsd.ssa: $(stdlib_datetime_freebsd_srcs) $(st
stdlib_dirs_any_srcs = \
$(STDLIB)/dirs/xdg.ha
-$(HARECACHE)/dirs/dirs-any.ssa: $(stdlib_dirs_any_srcs) $(stdlib_rt) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM))
+$(HARECACHE)/dirs/dirs-any.ssa: $(stdlib_dirs_any_srcs) $(stdlib_rt) $(stdlib_fs_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_os_$(PLATFORM)) $(stdlib_path_$(PLATFORM)) $(stdlib_fmt_$(PLATFORM)) $(stdlib_unix_$(PLATFORM))
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/dirs
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ndirs \
@@ -3173,7 +3173,7 @@ $(TESTCACHE)/datetime/datetime-freebsd.ssa: $(testlib_datetime_freebsd_srcs) $(t
testlib_dirs_any_srcs = \
$(STDLIB)/dirs/xdg.ha
-$(TESTCACHE)/dirs/dirs-any.ssa: $(testlib_dirs_any_srcs) $(testlib_rt) $(testlib_fs_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_fmt_$(PLATFORM))
+$(TESTCACHE)/dirs/dirs-any.ssa: $(testlib_dirs_any_srcs) $(testlib_rt) $(testlib_fs_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_os_$(PLATFORM)) $(testlib_path_$(PLATFORM)) $(testlib_fmt_$(PLATFORM)) $(testlib_unix_$(PLATFORM))
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/dirs
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ndirs \