commit 0c67a66b11bbb3e7832a2384e5b865d3feb5e0c7
parent a995aaa61bf2e6fe41d937df17433cdfef7a70c6
Author: Chris Bracken <chris@bracken.jp>
Date: Fri, 6 Mar 2026 17:31:10 +0900
cache: create cache temp file in target directory
Updates cache_open to create the temporary file template in the same
directory as the target cache path. Ensures that the temp file and the
final destination reside on the same filesystem, avoiding potential
EXDEV errors during the rename in cache_close_and_replace.
e.g., if the user provides an absolute path for the cache via -c
/var/cache/gout/db.cache and the current working directory is on a
different mount point than /var, renaming a temporary file from the
current directory to the target path would fail with EXDEV if the
system doesn't permit cross-device links.
Diffstat:
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/writer/cache/cache.c b/src/writer/cache/cache.c
@@ -2,6 +2,7 @@
#include <assert.h>
#include <err.h>
+#include <libgen.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -11,7 +12,7 @@
#include "git/git.h"
#include "utils.h"
-static const char* kTempCachePath = "cache.XXXXXXXXXXXX";
+static const char* kTempCacheTemplate = "cache.XXXXXXXXXXXX";
static const mode_t kReadWriteAll =
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
@@ -66,7 +67,11 @@ Cache* cache_open(const FileSystem* fs,
assert(path != NULL);
assert(write_func != NULL);
- char* temp_cache_path = estrdup(kTempCachePath);
+ char* path_copy = estrdup(path);
+ const char* dir = dirname(path_copy);
+ char* temp_cache_path = path_concat(dir, kTempCacheTemplate);
+ free(path_copy);
+
FILE* cache_in = fs->fopen(path, "r");
int out_fd = fs->mkstemp(temp_cache_path);
if (out_fd == -1) {