commit: 3807c8aa53785838bdb4d4d81c4eeaa993702b65
parent 1720a339814e5809d562f3c415118da0c1190c1d
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sun, 27 Jul 2025 17:42:13 +0200
cmd/mktemp: add support for suffixes
For compatibility with mktemp(1) from GNU coreutils and OpenBSD
Diffstat:
5 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/cmd/mktemp.c b/cmd/mktemp.c
@@ -21,12 +21,12 @@
const char *argv0 = "mktemp";
static int
-unsafe_mktemp(char *template)
+unsafe_mktemp(char *template, size_t suffix)
{
size_t l = strlen(template);
size_t len = 0;
- size_t off = l - 1;
+ size_t off = l - 1 - suffix;
while(off > 0 && template[off] == 'X')
off--, len++;
@@ -155,14 +155,26 @@ main(int argc, char *argv[])
printf("%s/", tmpdir);
}
+ char *suffix_start = strrchr(template, 'X');
+ if(!suffix_start)
+ {
+ fprintf(stderr, "%s: error: template '%s' does not contains any 'X'\n", argv0, template);
+ return 1;
+ }
+ size_t suffix_len = strlen(suffix_start + 1);
+
static char template_copy[PATH_MAX] = "";
memcpy(template_copy, template, PATH_MAX);
- if(o_unsafe) return unsafe_mktemp(template);
+ if(o_unsafe) return unsafe_mktemp(template, suffix_len);
if(o_create_dir)
{
+#ifdef HAS_MKDTEMPS
+ char *dir = mkdtemps(template, suffix_len);
+#else
char *dir = mkdtemp(template);
+#endif
if(dir == NULL)
{
if(!o_quiet)
@@ -180,7 +192,11 @@ main(int argc, char *argv[])
return 0;
}
+#ifdef HAS_MKSTEMPS
+ int fd = mkstemps(template, suffix_len);
+#else
int fd = mkstemp(template);
+#endif
if(fd < 0)
{
if(!o_quiet)
diff --git a/configure b/configure
@@ -262,6 +262,9 @@ if ! check_conftest configure.d/fgetln.c; then
target_filter="${target_filter} -e cmd/join."
fi
+check_conftest configure.d/mkstemps.c && cpp_define HAS_MKSTEMPS
+check_conftest configure.d/mkdtemps.c && cpp_define HAS_MKDTEMPS
+
rm -f configure.d/*.bin
echo
diff --git a/configure.d/mkdtemps.c b/configure.d/mkdtemps.c
@@ -0,0 +1,17 @@
+// utils-std: Collection of commonly available Unix tools
+// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+// SPDX-License-Identifier: MPL-2.0
+
+// Because that's what our utilities will use :)
+#define _DEFAULT_SOURCE
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ char template[] = "mktemp_XXXXXX.d";
+ size_t suffix = 2;
+
+ return mkdtemps(template, suffix);
+}
diff --git a/configure.d/mkstemps.c b/configure.d/mkstemps.c
@@ -0,0 +1,17 @@
+// utils-std: Collection of commonly available Unix tools
+// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+// SPDX-License-Identifier: MPL-2.0
+
+// Because that's what our utilities will use :)
+#define _DEFAULT_SOURCE
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+ char template[] = "mktemp_XXXXXX.c";
+ size_t suffix = 2;
+
+ return mkstemps(template, suffix);
+}
diff --git a/test-cmd/mktemp.sh b/test-cmd/mktemp.sh
@@ -2,9 +2,9 @@
# SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
# SPDX-License-Identifier: MPL-2.0
+plans=17
WD="$(dirname "$0")/../"
target="${WD}/cmd/mktemp"
-plans=15
. "${WD}/test-cmd/tap.sh"
t_mktemp()
@@ -113,3 +113,11 @@ else
t --exit=1 unknown_long_opt --foobar "mktemp: error: Long options unsupported: '--foobar'
"
fi
+
+if grep -q HAS_MKSTEMPS "${WD}/config.h"; then
+ t_mktemp suffix_file template.XXXXXX.txt
+else
+ skip suffix_file
+fi
+
+t_cmd unsafe:suffix_file '' cmd_mktemp_u -u template.XXXXXX.txt