summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2013-05-14 11:59:20 +0530
committerVijay Bellur <vbellur@redhat.com>2013-05-14 09:02:11 -0700
commitc59166c5a3306231864fe7d99e383259a9385233 (patch)
tree5c26c7ad26ed5be372eb0aceb190e90432fc9bad
parent3490689f29342116cf78cc57bc90ad1979d9e1bb (diff)
glusterfs: add gf_mkostemp api and use it instead of mkostemp of libc
Change-Id: Ia3d2f37ae1f7a7d87a75c82bedb4963729d45b6c BUG: 764890 Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-on: http://review.gluster.org/5004 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--contrib/stdlib/gf_mkostemp.c107
-rw-r--r--libglusterfs/src/Makefile.am3
-rw-r--r--libglusterfs/src/compat.h3
3 files changed, 112 insertions, 1 deletions
diff --git a/contrib/stdlib/gf_mkostemp.c b/contrib/stdlib/gf_mkostemp.c
new file mode 100644
index 000000000..931249a45
--- /dev/null
+++ b/contrib/stdlib/gf_mkostemp.c
@@ -0,0 +1,107 @@
+/* Borrowed from glibc-2.16/sysdeps/posix/tempname.c */
+
+/* Copyright (C) 1991-2001, 2006, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <time.h>
+#include <inttypes.h>
+
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary file name based on TMPL. TMPL must match the
+ rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
+*/
+
+#if !defined(TMP_MAX)
+#define TMP_MAX 238328
+#endif
+
+int
+gf_mkostemp (char *tmpl, int suffixlen, int flags)
+{
+ int len;
+ char *XXXXXX;
+ static uint64_t value;
+ uint64_t random_time_bits;
+ unsigned int count;
+ int fd = -1;
+
+ /* A lower bound on the number of temporary files to attempt to
+ generate. The maximum total number of temporary file names that
+ can exist for a given template is 62**6. It should never be
+ necessary to try all these combinations. Instead if a reasonable
+ number of names is tried (we define reasonable as 62**3) fail to
+ give the system administrator the chance to remove the problems. */
+
+ unsigned int attempts = TMP_MAX; /* TMP_MAX == 62³ */
+
+ len = strlen (tmpl);
+ if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen],
+ "XXXXXX", 6))
+ return -1;
+
+ /* This is where the Xs start. */
+ XXXXXX = &tmpl[len - 6 - suffixlen];
+
+ /* Get some more or less random data. */
+# if HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+# else
+ random_time_bits = time (NULL);
+# endif
+
+ value += random_time_bits ^ getpid ();
+
+ for (count = 0; count < attempts; value += 7777, ++count) {
+ uint64_t v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = open (tmpl, (flags & ~O_ACCMODE)
+ | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+
+ if (fd >= 0)
+ return fd;
+ else if (errno != EEXIST)
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ return -1;
+}
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index d708f98d2..ac1a9f58e 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -24,7 +24,8 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \
$(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c \
graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c \
event-history.c \
- $(CONTRIBDIR)/libgen/basename_r.c $(CONTRIBDIR)/libgen/dirname_r.c
+ $(CONTRIBDIR)/libgen/basename_r.c $(CONTRIBDIR)/libgen/dirname_r.c \
+ $(CONTRIBDIR)/stdlib/gf_mkostemp.c
nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c
diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h
index af890485d..3d0cee1a9 100644
--- a/libglusterfs/src/compat.h
+++ b/libglusterfs/src/compat.h
@@ -344,6 +344,9 @@ char *dirname_r(char *path);
#define dirname(path) dirname_r(path)
#endif /* THREAD_UNSAFE_DIRNAME */
+int gf_mkostemp (char *tmpl, int suffixlen, int flags);
+#define mkostemp(tmpl, flags) gf_mkostemp(tmpl, 0, flags);
+
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
/* Linux, Solaris, Cygwin */
#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)