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 *);