From 4c96047b6275561be165dc65dd459974a7e3cb5b Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Sun, 19 Sep 2021 15:05:39 +0000 Subject: Test availability of mkstemps(3) and provide a fallback implementation in case it is missing; needed for SUN Solaris 10. --- Makefile | 7 +++++-- Makefile.depend | 1 + compat_mkstemps.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure | 11 ++++++++-- test-mkstemps.c | 12 +++++++++++ 5 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 compat_mkstemps.c create mode 100644 test-mkstemps.c diff --git a/Makefile b/Makefile index 17d445bf..8e6ae5bb 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -# $Id: Makefile,v 1.536 2021/09/19 11:03:40 schwarze Exp $ +# $Id: Makefile,v 1.537 2021/09/19 15:05:39 schwarze Exp $ # -# Copyright (c) 2011, 2013-2020 Ingo Schwarze +# Copyright (c) 2011, 2013-2021 Ingo Schwarze # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons # # Permission to use, copy, modify, and distribute this software for any @@ -30,6 +30,7 @@ TESTSRCS = test-attribute.c \ test-getsubopt.c \ test-isblank.c \ test-mkdtemp.c \ + test-mkstemps.c \ test-nanosleep.c \ test-noop.c \ test-ntohl.c \ @@ -66,6 +67,7 @@ SRCS = arch.c \ compat_getsubopt.c \ compat_isblank.c \ compat_mkdtemp.c \ + compat_mkstemps.c \ compat_ohash.c \ compat_progname.c \ compat_reallocarray.c \ @@ -257,6 +259,7 @@ ALL_COBJS = compat_err.o \ compat_getsubopt.o \ compat_isblank.o \ compat_mkdtemp.o \ + compat_mkstemps.o \ compat_ohash.o \ compat_progname.o \ compat_reallocarray.o \ diff --git a/Makefile.depend b/Makefile.depend index 55916ce1..d5f6556c 100644 --- a/Makefile.depend +++ b/Makefile.depend @@ -9,6 +9,7 @@ compat_getline.o: compat_getline.c config.h compat_getsubopt.o: compat_getsubopt.c config.h compat_isblank.o: compat_isblank.c config.h compat_mkdtemp.o: compat_mkdtemp.c config.h +compat_mkstemps.o: compat_mkstemps.c config.h compat_ohash.o: compat_ohash.c config.h compat_ohash.h compat_progname.o: compat_progname.c config.h compat_reallocarray.o: compat_reallocarray.c config.h diff --git a/compat_mkstemps.c b/compat_mkstemps.c new file mode 100644 index 00000000..32394ffa --- /dev/null +++ b/compat_mkstemps.c @@ -0,0 +1,63 @@ +/* $Id: compat_mkstemps.c,v 1.1 2021/09/19 15:05:39 schwarze Exp $ */ +/* + * Copyright (c) 2015, 2021 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Parts of the algorithm of this function are inspired by OpenBSD + * mkdtemp(3) by Theo de Raadt and Todd Miller, but the code differs. + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include + +int +mkstemps(char *path, int suffixlen) +{ + char *start, *end, *cp; + int fd, tries; + char backup; + + end = strchr(path, '\0'); + if (suffixlen < 0 || suffixlen > end - path - 6) { + errno = EINVAL; + return -1; + } + end -= suffixlen; + for (start = end; start > path; start--) + if (start[-1] != 'X') + break; + + backup = *end; + for (tries = INT_MAX; tries; tries--) { + *end = '\0'; + cp = mktemp(path); + *end = backup; + if (cp == NULL) + return -1; + fd = open(path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); + if (fd != -1) + return fd; + for (cp = start; cp < end; cp++) + *cp = 'X'; + if (errno != EEXIST) + return -1; + } + errno = EEXIST; + return -1; +} diff --git a/configure b/configure index cce7d50f..c71205b7 100755 --- a/configure +++ b/configure @@ -1,8 +1,8 @@ #!/bin/sh # -# $Id: configure,v 1.79 2021/09/19 12:28:04 schwarze Exp $ +# $Id: configure,v 1.80 2021/09/19 15:05:39 schwarze Exp $ # -# Copyright (c) 2014-2020 Ingo Schwarze +# Copyright (c) 2014-2021 Ingo Schwarze # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -68,6 +68,7 @@ HAVE_GETSUBOPT= HAVE_ISBLANK= HAVE_LESS_T= HAVE_MKDTEMP= +HAVE_MKSTEMPS= HAVE_NANOSLEEP= HAVE_NTOHL= HAVE_O_DIRECTORY= @@ -307,6 +308,7 @@ runtest getline GETLINE || true runtest getsubopt GETSUBOPT "" -D_GNU_SOURCE || true runtest isblank ISBLANK || true runtest mkdtemp MKDTEMP || true +runtest mkstemps MKSTEMPS || true runtest nanosleep NANOSLEEP "${LD_NANOSLEEP}" "-lrt" || true runtest ntohl NTOHL || true runtest O_DIRECTORY O_DIRECTORY || true @@ -483,6 +485,7 @@ cat << __HEREDOC__ #define HAVE_ISBLANK ${HAVE_ISBLANK} #define HAVE_LESS_T ${HAVE_LESS_T} #define HAVE_MKDTEMP ${HAVE_MKDTEMP} +#define HAVE_MKSTEMPS ${HAVE_MKSTEMPS} #define HAVE_NTOHL ${HAVE_NTOHL} #define HAVE_PLEDGE ${HAVE_PLEDGE} #define HAVE_PROGNAME ${HAVE_PROGNAME} @@ -543,6 +546,10 @@ if [ ${HAVE_MKDTEMP} -eq 0 ]; then echo "extern char *mkdtemp(char *);" MANDOC_COBJS="${MANDOC_COBJS} compat_mkdtemp.o" fi +if [ ${HAVE_MKSTEMPS} -eq 0 ]; then + echo "extern int mkstemps(char *, int);" + MANDOC_COBJS="${MANDOC_COBJS} compat_mkstemps.o" +fi if [ ${HAVE_OHASH} -eq 0 ]; then MANDOC_COBJS="${MANDOC_COBJS} compat_ohash.o" fi diff --git a/test-mkstemps.c b/test-mkstemps.c new file mode 100644 index 00000000..31460dca --- /dev/null +++ b/test-mkstemps.c @@ -0,0 +1,12 @@ +#include +#include + +int +main(void) +{ + char filename[] = "/tmp/temp.XXXXXX.suffix"; + + if (mkstemps(filename, 7) == -1) + return 1; + return unlink(filename) == -1; +} -- cgit v1.2.3-56-ge451