wrapper: add git_mkdtemp()

Extend git_mkstemps_mode() to optionally call mkdir(2) instead of open(2), then use that ability to create a mkdtemp(3) replacement, git_mkdtemp(). We'll start using it in the next commit. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Dec 6, 2025 at 14:27 UTC e1ecf0dd6897eae1594b7e9345605b8f88485b95
2 files changed +21 -2
wrapper.c
+19 -2
@@ -446,7 +446,11 @@ int xmkstemp(char *filename_template)
446 #undef TMP_MAX
447 #define TMP_MAX 16384
448
449 -int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
449 +/*
450 + * Returns -1 on error, 0 if it created a directory, or an open file
451 + * descriptor to the created regular file.
452 + */
453 +static int git_mkdstemps_mode(char *pattern, int suffix_len, int mode, bool dir)
454 {
455 static const char letters[] =
456 "abcdefghijklmnopqrstuvwxyz"
@@ -488,7 +492,10 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
492 v /= num_letters;
493 }
494
491 - fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
495 + if (dir)
496 + fd = mkdir(pattern, mode);
497 + else
498 + fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
499 if (fd >= 0)
500 return fd;
501 /*
@@ -503,6 +510,16 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
510 return -1;
511 }
512
513 +char *git_mkdtemp(char *pattern)
514 +{
515 + return git_mkdstemps_mode(pattern, 0, 0700, true) ? NULL : pattern;
516 +}
517 +
518 +int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
519 +{
520 + return git_mkdstemps_mode(pattern, suffix_len, mode, false);
521 +}
522 +
523 int git_mkstemp_mode(char *pattern, int mode)
524 {
525 /* mkstemp is just mkstemps with no suffix */
wrapper.h
+2
@@ -37,6 +37,8 @@ int xsnprintf(char *dst, size_t max, const char *fmt, ...);
37
38 int xgethostname(char *buf, size_t len);
39
40 +char *git_mkdtemp(char *pattern);
41 +
42 /* set default permissions by passing mode arguments to open(2) */
43 int git_mkstemps_mode(char *pattern, int suffix_len, int mode);
44 int git_mkstemp_mode(char *pattern, int mode);