@matheusbsbs / matheus-bagliano / commits / 0620b39b3b
Fork 0

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>

David Aguilar committed May 31, 2009 at 01:35 UTC 0620b39b3b7b1f27bf863d9591fd8146a9a8931d
5 files changed +102
Makefile
+19
@@ -52,6 +52,8 @@ all::
52 #
53 # Define NO_MKDTEMP if you don't have mkdtemp in the C library.
54 #
55 +# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
56 +#
57 # Define NO_SYS_SELECT_H if you don't have sys/select.h.
58 #
59 # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
@@ -636,10 +638,12 @@ EXTLIBS =
638
639 ifeq ($(uname_S),Linux)
640 NO_STRLCPY = YesPlease
641 + NO_MKSTEMPS = YesPlease
642 THREADED_DELTA_SEARCH = YesPlease
643 endif
644 ifeq ($(uname_S),GNU/kFreeBSD)
645 NO_STRLCPY = YesPlease
646 + NO_MKSTEMPS = YesPlease
647 THREADED_DELTA_SEARCH = YesPlease
648 endif
649 ifeq ($(uname_S),UnixWare)
@@ -651,6 +655,7 @@ ifeq ($(uname_S),UnixWare)
655 SHELL_PATH = /usr/local/bin/bash
656 NO_IPV6 = YesPlease
657 NO_HSTRERROR = YesPlease
658 + NO_MKSTEMPS = YesPlease
659 BASIC_CFLAGS += -Kthread
660 BASIC_CFLAGS += -I/usr/local/include
661 BASIC_LDFLAGS += -L/usr/local/lib
@@ -674,6 +679,7 @@ ifeq ($(uname_S),SCO_SV)
679 SHELL_PATH = /usr/bin/bash
680 NO_IPV6 = YesPlease
681 NO_HSTRERROR = YesPlease
682 + NO_MKSTEMPS = YesPlease
683 BASIC_CFLAGS += -I/usr/local/include
684 BASIC_LDFLAGS += -L/usr/local/lib
685 NO_STRCASESTR = YesPlease
@@ -702,6 +708,7 @@ ifeq ($(uname_S),SunOS)
708 NO_MEMMEM = YesPlease
709 NO_HSTRERROR = YesPlease
710 NO_MKDTEMP = YesPlease
711 + NO_MKSTEMPS = YesPlease
712 OLD_ICONV = UnfortunatelyYes
713 ifeq ($(uname_R),5.8)
714 NO_UNSETENV = YesPlease
@@ -724,6 +731,7 @@ ifeq ($(uname_O),Cygwin)
731 NO_D_INO_IN_DIRENT = YesPlease
732 NO_STRCASESTR = YesPlease
733 NO_MEMMEM = YesPlease
734 + NO_MKSTEMPS = YesPlease
735 NO_SYMLINK_HEAD = YesPlease
736 NEEDS_LIBICONV = YesPlease
737 NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
@@ -767,11 +775,13 @@ ifeq ($(uname_S),NetBSD)
775 BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib
776 THREADED_DELTA_SEARCH = YesPlease
777 USE_ST_TIMESPEC = YesPlease
778 + NO_MKSTEMPS = YesPlease
779 endif
780 ifeq ($(uname_S),AIX)
781 NO_STRCASESTR=YesPlease
782 NO_MEMMEM = YesPlease
783 NO_MKDTEMP = YesPlease
784 + NO_MKSTEMPS = YesPlease
785 NO_STRLCPY = YesPlease
786 NO_NSEC = YesPlease
787 FREAD_READS_DIRECTORIES = UnfortunatelyYes
@@ -787,12 +797,14 @@ endif
797 ifeq ($(uname_S),GNU)
798 # GNU/Hurd
799 NO_STRLCPY=YesPlease
800 + NO_MKSTEMPS = YesPlease
801 endif
802 ifeq ($(uname_S),IRIX64)
803 NO_IPV6=YesPlease
804 NO_SETENV=YesPlease
805 NO_STRCASESTR=YesPlease
806 NO_MEMMEM = YesPlease
807 + NO_MKSTEMPS = YesPlease
808 NO_STRLCPY = YesPlease
809 NO_SOCKADDR_STORAGE=YesPlease
810 SHELL_PATH=/usr/gnu/bin/bash
@@ -805,6 +817,7 @@ ifeq ($(uname_S),HP-UX)
817 NO_SETENV=YesPlease
818 NO_STRCASESTR=YesPlease
819 NO_MEMMEM = YesPlease
820 + NO_MKSTEMPS = YesPlease
821 NO_STRLCPY = YesPlease
822 NO_MKDTEMP = YesPlease
823 NO_UNSETENV = YesPlease
@@ -834,6 +847,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
847 NO_C99_FORMAT = YesPlease
848 NO_STRTOUMAX = YesPlease
849 NO_MKDTEMP = YesPlease
850 + NO_MKSTEMPS = YesPlease
851 SNPRINTF_RETURNS_BOGUS = YesPlease
852 NO_SVN_TESTS = YesPlease
853 NO_PERL_MAKEMAKER = YesPlease
@@ -853,6 +867,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
867 endif
868 ifneq (,$(findstring arm,$(uname_M)))
869 ARM_SHA1 = YesPlease
870 + NO_MKSTEMPS = YesPlease
871 endif
872
873 -include config.mak.autogen
@@ -1011,6 +1026,10 @@ ifdef NO_MKDTEMP
1026 COMPAT_CFLAGS += -DNO_MKDTEMP
1027 COMPAT_OBJS += compat/mkdtemp.o
1028 endif
1029 +ifdef NO_MKSTEMPS
1030 + COMPAT_CFLAGS += -DNO_MKSTEMPS
1031 + COMPAT_OBJS += compat/mkstemps.o
1032 +endif
1033 ifdef NO_UNSETENV
1034 COMPAT_CFLAGS += -DNO_UNSETENV
1035 COMPAT_OBJS += compat/unsetenv.o
compat/mkstemps.c new
+70
@@ -0,0 +1,70 @@
1 +#include "../git-compat-util.h"
2 +
3 +/* Adapted from libiberty's mkstemp.c. */
4 +
5 +#undef TMP_MAX
6 +#define TMP_MAX 16384
7 +
8 +int gitmkstemps(char *pattern, int suffix_len)
9 +{
10 + static const char letters[] =
11 + "abcdefghijklmnopqrstuvwxyz"
12 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
13 + "0123456789";
14 + static const int num_letters = 62;
15 + uint64_t value;
16 + struct timeval tv;
17 + char *template;
18 + size_t len;
19 + int fd, count;
20 +
21 + len = strlen(pattern);
22 +
23 + if (len < 6 + suffix_len) {
24 + errno = EINVAL;
25 + return -1;
26 + }
27 +
28 + if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
29 + errno = EINVAL;
30 + return -1;
31 + }
32 +
33 + /*
34 + * Replace pattern's XXXXXX characters with randomness.
35 + * Try TMP_MAX different filenames.
36 + */
37 + gettimeofday(&tv, NULL);
38 + value = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();
39 + template = &pattern[len - 6 - suffix_len];
40 + for (count = 0; count < TMP_MAX; ++count) {
41 + uint64_t v = value;
42 + /* Fill in the random bits. */
43 + template[0] = letters[v % num_letters]; v /= num_letters;
44 + template[1] = letters[v % num_letters]; v /= num_letters;
45 + template[2] = letters[v % num_letters]; v /= num_letters;
46 + template[3] = letters[v % num_letters]; v /= num_letters;
47 + template[4] = letters[v % num_letters]; v /= num_letters;
48 + template[5] = letters[v % num_letters]; v /= num_letters;
49 +
50 + fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, 0600);
51 + if (fd > 0)
52 + return fd;
53 + /*
54 + * Fatal error (EPERM, ENOSPC etc).
55 + * It doesn't make sense to loop.
56 + */
57 + if (errno != EEXIST)
58 + break;
59 + /*
60 + * This is a random value. It is only necessary that
61 + * the next TMP_MAX values generated by adding 7777 to
62 + * VALUE are different with (module 2^32).
63 + */
64 + value += 7777;
65 + }
66 + /* We return the null string if we can't find a unique file name. */
67 + pattern[0] = '\0';
68 + errno = EINVAL;
69 + return -1;
70 +}
config.mak.in
+1
@@ -46,6 +46,7 @@ NO_STRTOUMAX=@NO_STRTOUMAX@
46 NO_SETENV=@NO_SETENV@
47 NO_UNSETENV=@NO_UNSETENV@
48 NO_MKDTEMP=@NO_MKDTEMP@
49 +NO_MKSTEMPS=@NO_MKSTEMPS@
50 NO_ICONV=@NO_ICONV@
51 OLD_ICONV=@OLD_ICONV@
52 NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
configure.ac
+7
@@ -677,6 +677,13 @@ GIT_CHECK_FUNC(mkdtemp,
677 [NO_MKDTEMP=YesPlease])
678 AC_SUBST(NO_MKDTEMP)
679 #
680 +# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
681 +GIT_CHECK_FUNC(mkstemps,
682 +[NO_MKSTEMPS=],
683 +[NO_MKSTEMPS=YesPlease])
684 +AC_SUBST(NO_MKSTEMPS)
685 +#
686 +#
687 # Define NO_MMAP if you want to avoid mmap.
688 #
689 # Define NO_ICONV if your libc does not properly support iconv.
git-compat-util.h
+5
@@ -232,6 +232,11 @@ extern int gitsetenv(const char *, const char *, int);
232 extern char *gitmkdtemp(char *);
233 #endif
234
235 +#ifdef NO_MKSTEMPS
236 +#define mkstemps gitmkstemps
237 +extern int gitmkstemps(char *, int);
238 +#endif
239 +
240 #ifdef NO_UNSETENV
241 #define unsetenv gitunsetenv
242 extern void gitunsetenv(const char *);