1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
/* SPDX-License-Identifier: MIT */
/* SPDX-FileCopyrightText: (c) Copyright 2025,2026 Andrew Bower <andrew@bower.uk> */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "options.h"
#include "dirs.h"
static const char *std_run_dir = "/run/" NAME_STR;
static const char *fallback_run_dir = "/tmp/run-" NAME_STR;
static int run_dir_fd = -1;
char *run_dir = NULL;
int ensure_dir(int dirfd, const char *path, int *fd, mode_t mode) {
for (int creating = 0; *fd == -1 && creating <= 1; creating++) {
*fd = openat(dirfd, path, O_DIRECTORY | O_CLOEXEC);
if (*fd == -1 && !creating && (errno == ENOENT))
mkdirat(dirfd, path, mode);
}
if (*fd == -1 && errno != EEXIST)
return -1;
return 0;
}
int get_run_dir(void) {
int rc;
if (run_dir_fd != -1)
return run_dir_fd;
rc = ensure_dir(-1, std_run_dir, &run_dir_fd, 0700);
if (rc == -1) {
char *xdg_run_dir = getenv("XDG_RUNTIME_DIR");
if (xdg_run_dir) {
char *path;
rc = asprintf(&path, "%s/%s", xdg_run_dir, NAME_STR);
if (rc != -1) {
rc = ensure_dir(-1, path, &run_dir_fd, 0700);
if (rc != -1) {
run_dir = path;
} else {
free(path);
}
}
}
} else {
run_dir = strdup(std_run_dir);
}
if (rc == -1 &&
ensure_dir(-1, fallback_run_dir, &run_dir_fd, 0700) != -1)
run_dir = strdup(fallback_run_dir);
return run_dir_fd;
}
const char *get_run_path(void) {
get_run_dir();
return run_dir;
}
void close_run_dir(void) {
if (run_dir_fd != -1) {
close(run_dir_fd);
run_dir_fd = -1;
}
free(run_dir);
run_dir = NULL;
}
|