mirror of
https://github.com/git/git
synced 2024-08-28 12:09:19 +00:00
compat: add a mkstemps() compatibility function
mkstemps() is a BSD extension so provide an implementation for cross-platform use. Signed-off-by: David Aguilar <davvid@gmail.com> Tested-by: Johannes Sixt <j6t@kdbg.org> (Windows) Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
33fd7169ed
commit
0620b39b3b
19
Makefile
19
Makefile
|
@ -52,6 +52,8 @@ all::
|
||||||
#
|
#
|
||||||
# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
|
# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
|
||||||
#
|
#
|
||||||
|
# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
|
||||||
|
#
|
||||||
# Define NO_SYS_SELECT_H if you don't have sys/select.h.
|
# Define NO_SYS_SELECT_H if you don't have sys/select.h.
|
||||||
#
|
#
|
||||||
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
|
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
|
||||||
|
@ -636,10 +638,12 @@ EXTLIBS =
|
||||||
|
|
||||||
ifeq ($(uname_S),Linux)
|
ifeq ($(uname_S),Linux)
|
||||||
NO_STRLCPY = YesPlease
|
NO_STRLCPY = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
THREADED_DELTA_SEARCH = YesPlease
|
THREADED_DELTA_SEARCH = YesPlease
|
||||||
endif
|
endif
|
||||||
ifeq ($(uname_S),GNU/kFreeBSD)
|
ifeq ($(uname_S),GNU/kFreeBSD)
|
||||||
NO_STRLCPY = YesPlease
|
NO_STRLCPY = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
THREADED_DELTA_SEARCH = YesPlease
|
THREADED_DELTA_SEARCH = YesPlease
|
||||||
endif
|
endif
|
||||||
ifeq ($(uname_S),UnixWare)
|
ifeq ($(uname_S),UnixWare)
|
||||||
|
@ -651,6 +655,7 @@ ifeq ($(uname_S),UnixWare)
|
||||||
SHELL_PATH = /usr/local/bin/bash
|
SHELL_PATH = /usr/local/bin/bash
|
||||||
NO_IPV6 = YesPlease
|
NO_IPV6 = YesPlease
|
||||||
NO_HSTRERROR = YesPlease
|
NO_HSTRERROR = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
BASIC_CFLAGS += -Kthread
|
BASIC_CFLAGS += -Kthread
|
||||||
BASIC_CFLAGS += -I/usr/local/include
|
BASIC_CFLAGS += -I/usr/local/include
|
||||||
BASIC_LDFLAGS += -L/usr/local/lib
|
BASIC_LDFLAGS += -L/usr/local/lib
|
||||||
|
@ -674,6 +679,7 @@ ifeq ($(uname_S),SCO_SV)
|
||||||
SHELL_PATH = /usr/bin/bash
|
SHELL_PATH = /usr/bin/bash
|
||||||
NO_IPV6 = YesPlease
|
NO_IPV6 = YesPlease
|
||||||
NO_HSTRERROR = YesPlease
|
NO_HSTRERROR = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
BASIC_CFLAGS += -I/usr/local/include
|
BASIC_CFLAGS += -I/usr/local/include
|
||||||
BASIC_LDFLAGS += -L/usr/local/lib
|
BASIC_LDFLAGS += -L/usr/local/lib
|
||||||
NO_STRCASESTR = YesPlease
|
NO_STRCASESTR = YesPlease
|
||||||
|
@ -702,6 +708,7 @@ ifeq ($(uname_S),SunOS)
|
||||||
NO_MEMMEM = YesPlease
|
NO_MEMMEM = YesPlease
|
||||||
NO_HSTRERROR = YesPlease
|
NO_HSTRERROR = YesPlease
|
||||||
NO_MKDTEMP = YesPlease
|
NO_MKDTEMP = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
OLD_ICONV = UnfortunatelyYes
|
OLD_ICONV = UnfortunatelyYes
|
||||||
ifeq ($(uname_R),5.8)
|
ifeq ($(uname_R),5.8)
|
||||||
NO_UNSETENV = YesPlease
|
NO_UNSETENV = YesPlease
|
||||||
|
@ -724,6 +731,7 @@ ifeq ($(uname_O),Cygwin)
|
||||||
NO_D_INO_IN_DIRENT = YesPlease
|
NO_D_INO_IN_DIRENT = YesPlease
|
||||||
NO_STRCASESTR = YesPlease
|
NO_STRCASESTR = YesPlease
|
||||||
NO_MEMMEM = YesPlease
|
NO_MEMMEM = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
NO_SYMLINK_HEAD = YesPlease
|
NO_SYMLINK_HEAD = YesPlease
|
||||||
NEEDS_LIBICONV = YesPlease
|
NEEDS_LIBICONV = YesPlease
|
||||||
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
|
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
|
||||||
|
@ -767,11 +775,13 @@ ifeq ($(uname_S),NetBSD)
|
||||||
BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib
|
BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib
|
||||||
THREADED_DELTA_SEARCH = YesPlease
|
THREADED_DELTA_SEARCH = YesPlease
|
||||||
USE_ST_TIMESPEC = YesPlease
|
USE_ST_TIMESPEC = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
endif
|
endif
|
||||||
ifeq ($(uname_S),AIX)
|
ifeq ($(uname_S),AIX)
|
||||||
NO_STRCASESTR=YesPlease
|
NO_STRCASESTR=YesPlease
|
||||||
NO_MEMMEM = YesPlease
|
NO_MEMMEM = YesPlease
|
||||||
NO_MKDTEMP = YesPlease
|
NO_MKDTEMP = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
NO_STRLCPY = YesPlease
|
NO_STRLCPY = YesPlease
|
||||||
NO_NSEC = YesPlease
|
NO_NSEC = YesPlease
|
||||||
FREAD_READS_DIRECTORIES = UnfortunatelyYes
|
FREAD_READS_DIRECTORIES = UnfortunatelyYes
|
||||||
|
@ -787,12 +797,14 @@ endif
|
||||||
ifeq ($(uname_S),GNU)
|
ifeq ($(uname_S),GNU)
|
||||||
# GNU/Hurd
|
# GNU/Hurd
|
||||||
NO_STRLCPY=YesPlease
|
NO_STRLCPY=YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
endif
|
endif
|
||||||
ifeq ($(uname_S),IRIX64)
|
ifeq ($(uname_S),IRIX64)
|
||||||
NO_IPV6=YesPlease
|
NO_IPV6=YesPlease
|
||||||
NO_SETENV=YesPlease
|
NO_SETENV=YesPlease
|
||||||
NO_STRCASESTR=YesPlease
|
NO_STRCASESTR=YesPlease
|
||||||
NO_MEMMEM = YesPlease
|
NO_MEMMEM = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
NO_STRLCPY = YesPlease
|
NO_STRLCPY = YesPlease
|
||||||
NO_SOCKADDR_STORAGE=YesPlease
|
NO_SOCKADDR_STORAGE=YesPlease
|
||||||
SHELL_PATH=/usr/gnu/bin/bash
|
SHELL_PATH=/usr/gnu/bin/bash
|
||||||
|
@ -805,6 +817,7 @@ ifeq ($(uname_S),HP-UX)
|
||||||
NO_SETENV=YesPlease
|
NO_SETENV=YesPlease
|
||||||
NO_STRCASESTR=YesPlease
|
NO_STRCASESTR=YesPlease
|
||||||
NO_MEMMEM = YesPlease
|
NO_MEMMEM = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
NO_STRLCPY = YesPlease
|
NO_STRLCPY = YesPlease
|
||||||
NO_MKDTEMP = YesPlease
|
NO_MKDTEMP = YesPlease
|
||||||
NO_UNSETENV = YesPlease
|
NO_UNSETENV = YesPlease
|
||||||
|
@ -834,6 +847,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
||||||
NO_C99_FORMAT = YesPlease
|
NO_C99_FORMAT = YesPlease
|
||||||
NO_STRTOUMAX = YesPlease
|
NO_STRTOUMAX = YesPlease
|
||||||
NO_MKDTEMP = YesPlease
|
NO_MKDTEMP = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||||
NO_SVN_TESTS = YesPlease
|
NO_SVN_TESTS = YesPlease
|
||||||
NO_PERL_MAKEMAKER = YesPlease
|
NO_PERL_MAKEMAKER = YesPlease
|
||||||
|
@ -853,6 +867,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
||||||
endif
|
endif
|
||||||
ifneq (,$(findstring arm,$(uname_M)))
|
ifneq (,$(findstring arm,$(uname_M)))
|
||||||
ARM_SHA1 = YesPlease
|
ARM_SHA1 = YesPlease
|
||||||
|
NO_MKSTEMPS = YesPlease
|
||||||
endif
|
endif
|
||||||
|
|
||||||
-include config.mak.autogen
|
-include config.mak.autogen
|
||||||
|
@ -1011,6 +1026,10 @@ ifdef NO_MKDTEMP
|
||||||
COMPAT_CFLAGS += -DNO_MKDTEMP
|
COMPAT_CFLAGS += -DNO_MKDTEMP
|
||||||
COMPAT_OBJS += compat/mkdtemp.o
|
COMPAT_OBJS += compat/mkdtemp.o
|
||||||
endif
|
endif
|
||||||
|
ifdef NO_MKSTEMPS
|
||||||
|
COMPAT_CFLAGS += -DNO_MKSTEMPS
|
||||||
|
COMPAT_OBJS += compat/mkstemps.o
|
||||||
|
endif
|
||||||
ifdef NO_UNSETENV
|
ifdef NO_UNSETENV
|
||||||
COMPAT_CFLAGS += -DNO_UNSETENV
|
COMPAT_CFLAGS += -DNO_UNSETENV
|
||||||
COMPAT_OBJS += compat/unsetenv.o
|
COMPAT_OBJS += compat/unsetenv.o
|
||||||
|
|
70
compat/mkstemps.c
Normal file
70
compat/mkstemps.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#include "../git-compat-util.h"
|
||||||
|
|
||||||
|
/* Adapted from libiberty's mkstemp.c. */
|
||||||
|
|
||||||
|
#undef TMP_MAX
|
||||||
|
#define TMP_MAX 16384
|
||||||
|
|
||||||
|
int gitmkstemps(char *pattern, int suffix_len)
|
||||||
|
{
|
||||||
|
static const char letters[] =
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"0123456789";
|
||||||
|
static const int num_letters = 62;
|
||||||
|
uint64_t value;
|
||||||
|
struct timeval tv;
|
||||||
|
char *template;
|
||||||
|
size_t len;
|
||||||
|
int fd, count;
|
||||||
|
|
||||||
|
len = strlen(pattern);
|
||||||
|
|
||||||
|
if (len < 6 + suffix_len) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replace pattern's XXXXXX characters with randomness.
|
||||||
|
* Try TMP_MAX different filenames.
|
||||||
|
*/
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
value = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();
|
||||||
|
template = &pattern[len - 6 - suffix_len];
|
||||||
|
for (count = 0; count < TMP_MAX; ++count) {
|
||||||
|
uint64_t v = value;
|
||||||
|
/* Fill in the random bits. */
|
||||||
|
template[0] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[1] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[2] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[3] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[4] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[5] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
|
||||||
|
fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);
|
||||||
|
if (fd > 0)
|
||||||
|
return fd;
|
||||||
|
/*
|
||||||
|
* Fatal error (EPERM, ENOSPC etc).
|
||||||
|
* It doesn't make sense to loop.
|
||||||
|
*/
|
||||||
|
if (errno != EEXIST)
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* This is a random value. It is only necessary that
|
||||||
|
* the next TMP_MAX values generated by adding 7777 to
|
||||||
|
* VALUE are different with (module 2^32).
|
||||||
|
*/
|
||||||
|
value += 7777;
|
||||||
|
}
|
||||||
|
/* We return the null string if we can't find a unique file name. */
|
||||||
|
pattern[0] = '\0';
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -46,6 +46,7 @@ NO_STRTOUMAX=@NO_STRTOUMAX@
|
||||||
NO_SETENV=@NO_SETENV@
|
NO_SETENV=@NO_SETENV@
|
||||||
NO_UNSETENV=@NO_UNSETENV@
|
NO_UNSETENV=@NO_UNSETENV@
|
||||||
NO_MKDTEMP=@NO_MKDTEMP@
|
NO_MKDTEMP=@NO_MKDTEMP@
|
||||||
|
NO_MKSTEMPS=@NO_MKSTEMPS@
|
||||||
NO_ICONV=@NO_ICONV@
|
NO_ICONV=@NO_ICONV@
|
||||||
OLD_ICONV=@OLD_ICONV@
|
OLD_ICONV=@OLD_ICONV@
|
||||||
NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
|
NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
|
||||||
|
|
|
@ -677,6 +677,13 @@ GIT_CHECK_FUNC(mkdtemp,
|
||||||
[NO_MKDTEMP=YesPlease])
|
[NO_MKDTEMP=YesPlease])
|
||||||
AC_SUBST(NO_MKDTEMP)
|
AC_SUBST(NO_MKDTEMP)
|
||||||
#
|
#
|
||||||
|
# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
|
||||||
|
GIT_CHECK_FUNC(mkstemps,
|
||||||
|
[NO_MKSTEMPS=],
|
||||||
|
[NO_MKSTEMPS=YesPlease])
|
||||||
|
AC_SUBST(NO_MKSTEMPS)
|
||||||
|
#
|
||||||
|
#
|
||||||
# Define NO_MMAP if you want to avoid mmap.
|
# Define NO_MMAP if you want to avoid mmap.
|
||||||
#
|
#
|
||||||
# Define NO_ICONV if your libc does not properly support iconv.
|
# Define NO_ICONV if your libc does not properly support iconv.
|
||||||
|
|
|
@ -232,6 +232,11 @@ extern int gitsetenv(const char *, const char *, int);
|
||||||
extern char *gitmkdtemp(char *);
|
extern char *gitmkdtemp(char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_MKSTEMPS
|
||||||
|
#define mkstemps gitmkstemps
|
||||||
|
extern int gitmkstemps(char *, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NO_UNSETENV
|
#ifdef NO_UNSETENV
|
||||||
#define unsetenv gitunsetenv
|
#define unsetenv gitunsetenv
|
||||||
extern void gitunsetenv(const char *);
|
extern void gitunsetenv(const char *);
|
||||||
|
|
Loading…
Reference in a new issue