]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
add the mkstemp module from gnulib
authorJim Meyering <meyering@redhat.com>
Thu, 7 Aug 2008 13:02:45 +0000 (13:02 +0000)
committerJim Meyering <meyering@redhat.com>
Thu, 7 Aug 2008 13:02:45 +0000 (13:02 +0000)
* bootstrap (modules): Add mkstemp.
The remainder of these changes are the result of running
./bootstrap, adding new files, and committing the result.
* gnulib/lib/gettimeofday.c: New file.
* gnulib/lib/mkstemp.c: New file.
* gnulib/lib/tempname.c: New file.
* gnulib/lib/tempname.h: New file.
* gnulib/m4/gettimeofday.m4: New file.
* gnulib/m4/mkstemp.m4: New file.
* gnulib/m4/tempname.m4: New file.
* gnulib/tests/test-gettimeofday.c: New file.
* gnulib/lib/Makefile.am: Update.
* gnulib/m4/gnulib-cache.m4: Likewise.
* gnulib/m4/gnulib-comp.m4: Likewise.
* gnulib/m4/inet_pton.m4: Likewise.
* gnulib/tests/Makefile.am: Likewise.

15 files changed:
ChangeLog
bootstrap
gnulib/lib/Makefile.am
gnulib/lib/gettimeofday.c [new file with mode: 0644]
gnulib/lib/mkstemp.c [new file with mode: 0644]
gnulib/lib/tempname.c [new file with mode: 0644]
gnulib/lib/tempname.h [new file with mode: 0644]
gnulib/m4/gettimeofday.m4 [new file with mode: 0644]
gnulib/m4/gnulib-cache.m4
gnulib/m4/gnulib-comp.m4
gnulib/m4/inet_pton.m4
gnulib/m4/mkstemp.m4 [new file with mode: 0644]
gnulib/m4/tempname.m4 [new file with mode: 0644]
gnulib/tests/Makefile.am
gnulib/tests/test-gettimeofday.c [new file with mode: 0644]

index c83b9af5dc94ced848b696e14638bb78afca2aaf..78a8f213b7701954502eb0a6cd7c99520907b000 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+Wed Aug  7 15:02:06 CEST 2008 Jim Meyering <meyering@redhat.com>
+
+       add the mkstemp module from gnulib
+       * bootstrap (modules): Add mkstemp.
+       The remainder of these changes are the result of running
+       ./bootstrap, adding new files, and committing the result.
+       * gnulib/lib/gettimeofday.c: New file.
+       * gnulib/lib/mkstemp.c: New file.
+       * gnulib/lib/tempname.c: New file.
+       * gnulib/lib/tempname.h: New file.
+       * gnulib/m4/gettimeofday.m4: New file.
+       * gnulib/m4/mkstemp.m4: New file.
+       * gnulib/m4/tempname.m4: New file.
+       * gnulib/tests/test-gettimeofday.c: New file.
+       * gnulib/lib/Makefile.am: Update.
+       * gnulib/m4/gnulib-cache.m4: Likewise.
+       * gnulib/m4/gnulib-comp.m4: Likewise.
+       * gnulib/m4/inet_pton.m4: Likewise.
+       * gnulib/tests/Makefile.am: Likewise.
+
 Thu Aug  7 12:21:31 CEST 2008 Daniel Veillard <veillard@redhat.com>
 
        * src/bridge.c: fix a build failure on RHEL4
index 70b9a05680a0de27d4cdc400ed1f65450d3d341b..f8fcb30dd57826e7e7bc804801a04908017c78b0 100755 (executable)
--- a/bootstrap
+++ b/bootstrap
@@ -70,6 +70,7 @@ getaddrinfo
 getpass
 gettext
 inet_pton
+mkstemp
 mktempd
 physmem
 poll
index 576b95123117ed9ca9e52e4b6c1e71bad35e15b1..3a7ba31a845698781784f5e95d00cf76964f01b3 100644 (file)
@@ -9,7 +9,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl c-ctype getaddrinfo getpass gettext inet_pton mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files verify
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl c-ctype getaddrinfo getpass gettext inet_pton mkstemp mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files verify
 
 AUTOMAKE_OPTIONS = 1.5 gnits
 
@@ -172,6 +172,15 @@ libgnu_la_SOURCES += gettext.h
 
 ## end   gnulib module gettext-h
 
+## begin gnulib module gettimeofday
+
+
+EXTRA_DIST += gettimeofday.c
+
+EXTRA_libgnu_la_SOURCES += gettimeofday.c
+
+## end   gnulib module gettimeofday
+
 ## begin gnulib module havelib
 
 
@@ -223,6 +232,15 @@ EXTRA_libgnu_la_SOURCES += malloc.c
 
 ## end   gnulib module malloc-posix
 
+## begin gnulib module mkstemp
+
+
+EXTRA_DIST += mkstemp.c
+
+EXTRA_libgnu_la_SOURCES += mkstemp.c
+
+## end   gnulib module mkstemp
+
 ## begin gnulib module mktempd
 
 
@@ -702,6 +720,15 @@ EXTRA_DIST += sys_time.in.h
 
 ## end   gnulib module sys_time
 
+## begin gnulib module tempname
+
+
+EXTRA_DIST += tempname.c tempname.h
+
+EXTRA_libgnu_la_SOURCES += tempname.c
+
+## end   gnulib module tempname
+
 ## begin gnulib module unistd
 
 BUILT_SOURCES += unistd.h
diff --git a/gnulib/lib/gettimeofday.c b/gnulib/lib/gettimeofday.c
new file mode 100644 (file)
index 0000000..75339c4
--- /dev/null
@@ -0,0 +1,142 @@
+/* Provide gettimeofday for systems that don't have it or for which it's broken.
+
+   Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007 Free Software
+   Foundation, Inc.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program 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 this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+/* Specification.  */
+#include <sys/time.h>
+
+#include <time.h>
+
+#if HAVE_SYS_TIMEB_H
+# include <sys/timeb.h>
+#endif
+
+#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
+
+/* Work around the bug in some systems whereby gettimeofday clobbers
+   the static buffer that localtime uses for its return value.  The
+   gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
+   this problem.  The tzset replacement is necessary for at least
+   Solaris 2.5, 2.5.1, and 2.6.  */
+
+static struct tm tm_zero_buffer;
+static struct tm *localtime_buffer_addr = &tm_zero_buffer;
+
+/* This is a wrapper for localtime.  It is used only on systems for which
+   gettimeofday clobbers the static buffer used for localtime's result.
+
+   On the first call, record the address of the static buffer that
+   localtime uses for its result.  */
+
+struct tm *
+rpl_localtime (time_t const *timep)
+{
+#undef localtime
+  extern struct tm *localtime (time_t const *);
+  struct tm *tm = localtime (timep);
+
+  if (localtime_buffer_addr == &tm_zero_buffer)
+    localtime_buffer_addr = tm;
+
+  return tm;
+}
+
+/* Same as above, since gmtime and localtime use the same buffer.  */
+struct tm *
+rpl_gmtime (time_t const *timep)
+{
+#undef gmtime
+  extern struct tm *gmtime (time_t const *);
+  struct tm *tm = gmtime (timep);
+
+  if (localtime_buffer_addr == &tm_zero_buffer)
+    localtime_buffer_addr = tm;
+
+  return tm;
+}
+
+#endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */
+
+#if TZSET_CLOBBERS_LOCALTIME
+/* This is a wrapper for tzset, for systems on which tzset may clobber
+   the static buffer used for localtime's result.  */
+void
+rpl_tzset (void)
+{
+#undef tzset
+  extern void tzset (void);
+
+  /* Save and restore the contents of the buffer used for localtime's
+     result around the call to tzset.  */
+  struct tm save = *localtime_buffer_addr;
+  tzset ();
+  *localtime_buffer_addr = save;
+}
+#endif
+
+/* This is a wrapper for gettimeofday.  It is used only on systems
+   that lack this function, or whose implementation of this function
+   causes problems.  */
+
+int
+rpl_gettimeofday (struct timeval *restrict tv, void *restrict tz)
+{
+#undef gettimeofday
+#if HAVE_GETTIMEOFDAY
+# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
+  /* Save and restore the contents of the buffer used for localtime's
+     result around the call to gettimeofday.  */
+  struct tm save = *localtime_buffer_addr;
+# endif
+
+  int result = gettimeofday (tv, tz);
+
+# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
+  *localtime_buffer_addr = save;
+# endif
+
+  return result;
+
+#else
+
+# if HAVE__FTIME
+
+  struct _timeb timebuf;
+  _ftime (&timebuf);
+  tv->tv_sec = timebuf.time;
+  tv->tv_usec = timebuf.millitm * 1000;
+
+# else
+
+#  if !defined OK_TO_USE_1S_CLOCK
+#   error "Only 1-second nominal clock resolution found.  Is that intended?" \
+          "If so, compile with the -DOK_TO_USE_1S_CLOCK option."
+#  endif
+  tv->tv_sec = time (NULL);
+  tv->tv_usec = 0;
+
+# endif
+
+  return 0;
+
+#endif
+}
diff --git a/gnulib/lib/mkstemp.c b/gnulib/lib/mkstemp.c
new file mode 100644 (file)
index 0000000..fcd44d9
--- /dev/null
@@ -0,0 +1,44 @@
+/* Copyright (C) 1998, 1999, 2001, 2005, 2006, 2007 Free Software Foundation, Inc.
+   This file is derived from the one in the GNU C Library.
+
+   This program 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.
+
+   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#if !_LIBC
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#if !_LIBC
+# include "tempname.h"
+# define __gen_tempname gen_tempname
+# define __GT_FILE GT_FILE
+#endif
+
+#include <stdio.h>
+
+#ifndef __GT_FILE
+# define __GT_FILE 0
+#endif
+
+/* Generate a unique temporary file name from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   Then open the file and return a fd. */
+int
+mkstemp (template)
+     char *template;
+{
+  return __gen_tempname (template, __GT_FILE);
+}
diff --git a/gnulib/lib/tempname.c b/gnulib/lib/tempname.c
new file mode 100644 (file)
index 0000000..2d5e5ed
--- /dev/null
@@ -0,0 +1,314 @@
+/* tempname.c - generate the name of a temporary file.
+
+   Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation,
+   Inc.
+
+   This program 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.
+
+   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Extracted from glibc sysdeps/posix/tempname.c.  See also tmpdir.c.  */
+
+#if !_LIBC
+# include <config.h>
+# include "tempname.h"
+#endif
+
+#include <sys/types.h>
+#include <assert.h>
+
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
+
+#include <stdio.h>
+#ifndef P_tmpdir
+# define P_tmpdir "/tmp"
+#endif
+#ifndef TMP_MAX
+# define TMP_MAX 238328
+#endif
+#ifndef __GT_FILE
+# define __GT_FILE     0
+# define __GT_BIGFILE  1
+# define __GT_DIR      2
+# define __GT_NOCREATE 3
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <sys/stat.h>
+
+#if _LIBC
+# define struct_stat64 struct stat64
+# define small_open __open
+# define large_open __open64
+#else
+# define struct_stat64 struct stat
+# define small_open open
+# define large_open open
+# define __gen_tempname gen_tempname
+# define __getpid getpid
+# define __gettimeofday gettimeofday
+# define __mkdir mkdir
+# define __lxstat64(version, file, buf) lstat (file, buf)
+# define __xstat64(version, file, buf) stat (file, buf)
+#endif
+
+#if ! (HAVE___SECURE_GETENV || _LIBC)
+# define __secure_getenv getenv
+#endif
+
+#ifdef _LIBC
+# include <hp-timing.h>
+# if HP_TIMING_AVAIL
+#  define RANDOM_BITS(Var) \
+  if (__builtin_expect (value == UINT64_C (0), 0))                           \
+    {                                                                        \
+      /* If this is the first time this function is used initialize          \
+        the variable we accumulate the value in to some somewhat             \
+        random value.  If we'd not do this programs at startup time          \
+        might have a reduced set of possible names, at least on slow         \
+        machines.  */                                                        \
+      struct timeval tv;                                                     \
+      __gettimeofday (&tv, NULL);                                            \
+      value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;                     \
+    }                                                                        \
+  HP_TIMING_NOW (Var)
+# endif
+#endif
+
+/* Use the widest available unsigned type if uint64_t is not
+   available.  The algorithm below extracts a number less than 62**6
+   (approximately 2**35.725) from uint64_t, so ancient hosts where
+   uintmax_t is only 32 bits lose about 3.725 bits of randomness,
+   which is better than not having mkstemp at all.  */
+#if !defined UINT64_MAX && !defined uint64_t
+# define uint64_t uintmax_t
+#endif
+
+#if _LIBC
+/* Return nonzero if DIR is an existent directory.  */
+static int
+direxists (const char *dir)
+{
+  struct_stat64 buf;
+  return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode);
+}
+
+/* Path search algorithm, for tmpnam, tmpfile, etc.  If DIR is
+   non-null and exists, uses it; otherwise uses the first of $TMPDIR,
+   P_tmpdir, /tmp that exists.  Copies into TMPL a template suitable
+   for use with mk[s]temp.  Will fail (-1) if DIR is non-null and
+   doesn't exist, none of the searched dirs exists, or there's not
+   enough space in TMPL. */
+int
+__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
+              int try_tmpdir)
+{
+  const char *d;
+  size_t dlen, plen;
+
+  if (!pfx || !pfx[0])
+    {
+      pfx = "file";
+      plen = 4;
+    }
+  else
+    {
+      plen = strlen (pfx);
+      if (plen > 5)
+       plen = 5;
+    }
+
+  if (try_tmpdir)
+    {
+      d = __secure_getenv ("TMPDIR");
+      if (d != NULL && direxists (d))
+       dir = d;
+      else if (dir != NULL && direxists (dir))
+       /* nothing */ ;
+      else
+       dir = NULL;
+    }
+  if (dir == NULL)
+    {
+      if (direxists (P_tmpdir))
+       dir = P_tmpdir;
+      else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
+       dir = "/tmp";
+      else
+       {
+         __set_errno (ENOENT);
+         return -1;
+       }
+    }
+
+  dlen = strlen (dir);
+  while (dlen > 1 && dir[dlen - 1] == '/')
+    dlen--;                    /* remove trailing slashes */
+
+  /* check we have room for "${dir}/${pfx}XXXXXX\0" */
+  if (tmpl_len < dlen + 1 + plen + 6 + 1)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
+  return 0;
+}
+#endif /* _LIBC */
+
+/* These are the characters used in temporary file names.  */
+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").  The name constructed
+   does not exist at the time of the call to __gen_tempname.  TMPL is
+   overwritten with the result.
+
+   KIND may be one of:
+   __GT_NOCREATE:      simply verify that the name does not exist
+                       at the time of the call.
+   __GT_FILE:          create the file using open(O_CREAT|O_EXCL)
+                       and return a read-write fd.  The file is mode 0600.
+   __GT_BIGFILE:       same as __GT_FILE but use open64().
+   __GT_DIR:           create a directory, which will be mode 0700.
+
+   We use a clever algorithm to get hard-to-predict names. */
+int
+__gen_tempname (char *tmpl, int kind)
+{
+  int len;
+  char *XXXXXX;
+  static uint64_t value;
+  uint64_t random_time_bits;
+  unsigned int count;
+  int fd = -1;
+  int save_errno = errno;
+  struct_stat64 st;
+
+  /* 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.  */
+#define ATTEMPTS_MIN (62 * 62 * 62)
+
+  /* The number of times to attempt to generate a temporary file.  To
+     conform to POSIX, this must be no smaller than TMP_MAX.  */
+#if ATTEMPTS_MIN < TMP_MAX
+  unsigned int attempts = TMP_MAX;
+#else
+  unsigned int attempts = ATTEMPTS_MIN;
+#endif
+
+  len = strlen (tmpl);
+  if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  /* This is where the Xs start.  */
+  XXXXXX = &tmpl[len - 6];
+
+  /* Get some more or less random data.  */
+#ifdef RANDOM_BITS
+  RANDOM_BITS (random_time_bits);
+#else
+  {
+    struct timeval tv;
+    __gettimeofday (&tv, NULL);
+    random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+  }
+#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];
+
+      switch (kind)
+       {
+       case __GT_FILE:
+         fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+         break;
+
+       case __GT_BIGFILE:
+         fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+         break;
+
+       case __GT_DIR:
+         fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
+         break;
+
+       case __GT_NOCREATE:
+         /* This case is backward from the other three.  __gen_tempname
+            succeeds if __xstat fails because the name does not exist.
+            Note the continue to bypass the common logic at the bottom
+            of the loop.  */
+         if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
+           {
+             if (errno == ENOENT)
+               {
+                 __set_errno (save_errno);
+                 return 0;
+               }
+             else
+               /* Give up now. */
+               return -1;
+           }
+         continue;
+
+       default:
+         assert (! "invalid KIND in __gen_tempname");
+       }
+
+      if (fd >= 0)
+       {
+         __set_errno (save_errno);
+         return fd;
+       }
+      else if (errno != EEXIST)
+       return -1;
+    }
+
+  /* We got out of the loop because we ran out of combinations to try.  */
+  __set_errno (EEXIST);
+  return -1;
+}
diff --git a/gnulib/lib/tempname.h b/gnulib/lib/tempname.h
new file mode 100644 (file)
index 0000000..e04a99d
--- /dev/null
@@ -0,0 +1,39 @@
+/* Create a temporary file or directory.
+
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* header written by Eric Blake */
+
+/* In gnulib, always prefer large files.  GT_FILE maps to
+   __GT_BIGFILE, not __GT_FILE, for a reason.  */
+#define GT_FILE                1
+#define GT_DIR         2
+#define GT_NOCREATE    3
+
+/* Generate a temporary file name based on TMPL.  TMPL must match the
+   rules for mk[s]temp (i.e. end in "XXXXXX").  The name constructed
+   does not exist at the time of the call to gen_tempname.  TMPL is
+   overwritten with the result.
+
+   KIND may be one of:
+   GT_NOCREATE:                simply verify that the name does not exist
+                       at the time of the call.
+   GT_FILE:            create a large file using open(O_CREAT|O_EXCL)
+                       and return a read-write fd.  The file is mode 0600.
+   GT_DIR:             create a directory, which will be mode 0700.
+
+   We use a clever algorithm to get hard-to-predict names. */
+extern int gen_tempname (char *tmpl, int kind);
diff --git a/gnulib/m4/gettimeofday.m4 b/gnulib/m4/gettimeofday.m4
new file mode 100644 (file)
index 0000000..b9bbb10
--- /dev/null
@@ -0,0 +1,101 @@
+#serial 11
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+dnl From Jim Meyering.
+
+AC_DEFUN([gl_FUNC_GETTIMEOFDAY],
+[
+  AC_REQUIRE([AC_C_RESTRICT])
+  AC_REQUIRE([gl_HEADER_SYS_TIME_H])
+  AC_CHECK_FUNCS_ONCE([gettimeofday])
+
+  AC_CACHE_CHECK([for gettimeofday with POSIX signature],
+    [gl_cv_func_gettimeofday_posix_signature],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+         [[#include <sys/time.h>
+           struct timeval c;
+         ]],
+         [[
+           int (*f) (struct timeval *restrict, void *restrict) = gettimeofday;
+           int x = f (&c, 0);
+           return !(x | c.tv_sec | c.tv_usec);
+         ]])],
+       [gl_cv_func_gettimeofday_posix_signature=yes],
+       [gl_cv_func_gettimeofday_posix_signature=no])])
+
+  gl_FUNC_GETTIMEOFDAY_CLOBBER
+
+  if test $gl_cv_func_gettimeofday_posix_signature != yes; then
+    REPLACE_GETTIMEOFDAY=1
+    SYS_TIME_H=sys/time.h
+    if test $gl_cv_func_gettimeofday_clobber != yes; then
+      AC_LIBOBJ(gettimeofday)
+      gl_PREREQ_GETTIMEOFDAY
+    fi
+  fi
+])
+
+
+dnl See if gettimeofday clobbers the static buffer that localtime uses
+dnl for its return value.  The gettimeofday function from Mac OS X 10.0.4
+dnl (i.e., Darwin 1.3.7) has this problem.
+dnl
+dnl If it does, then arrange to use gettimeofday and localtime only via
+dnl the wrapper functions that work around the problem.
+
+AC_DEFUN([gl_FUNC_GETTIMEOFDAY_CLOBBER],
+[
+ AC_REQUIRE([gl_HEADER_SYS_TIME_H])
+
+ AC_CACHE_CHECK([whether gettimeofday clobbers localtime buffer],
+  [gl_cv_func_gettimeofday_clobber],
+  [AC_RUN_IFELSE(
+     [AC_LANG_PROGRAM(
+       [[#include <string.h>
+         #include <sys/time.h>
+         #include <time.h>
+         #include <stdlib.h>
+       ]],
+       [[
+         time_t t = 0;
+         struct tm *lt;
+         struct tm saved_lt;
+         struct timeval tv;
+         lt = localtime (&t);
+         saved_lt = *lt;
+         gettimeofday (&tv, NULL);
+         return memcmp (lt, &saved_lt, sizeof (struct tm)) != 0;
+       ]])],
+     [gl_cv_func_gettimeofday_clobber=no],
+     [gl_cv_func_gettimeofday_clobber=yes],
+     dnl When crosscompiling, assume it is broken.
+     [gl_cv_func_gettimeofday_clobber=yes])])
+
+ if test $gl_cv_func_gettimeofday_clobber = yes; then
+   REPLACE_GETTIMEOFDAY=1
+   SYS_TIME_H=sys/time.h
+   gl_GETTIMEOFDAY_REPLACE_LOCALTIME
+   AC_DEFINE([GETTIMEOFDAY_CLOBBERS_LOCALTIME], 1,
+     [Define if gettimeofday clobbers the localtime buffer.])
+ fi
+])
+
+AC_DEFUN([gl_GETTIMEOFDAY_REPLACE_LOCALTIME], [
+  AC_LIBOBJ(gettimeofday)
+  gl_PREREQ_GETTIMEOFDAY
+  AC_DEFINE([gmtime], [rpl_gmtime],
+    [Define to rpl_gmtime if the replacement function should be used.])
+  AC_DEFINE([localtime], [rpl_localtime],
+    [Define to rpl_localtime if the replacement function should be used.])
+])
+
+# Prerequisites of lib/gettimeofday.c.
+AC_DEFUN([gl_PREREQ_GETTIMEOFDAY], [
+  AC_CHECK_HEADERS([sys/timeb.h])
+  AC_CHECK_FUNCS([_ftime])
+])
index d26e7f05d5637632987c71a5cdee7fc3878c26ee..ac9e993fc7b797f6eed0b99675d998b82c1a5e0d 100644 (file)
@@ -15,7 +15,7 @@
 
 
 # Specification in the form of a command-line invocation:
-#   gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl c-ctype getaddrinfo getpass gettext inet_pton mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files verify
+#   gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl c-ctype getaddrinfo getpass gettext inet_pton mkstemp mktempd physmem poll posix-shell strndup strsep sys_stat useless-if-before-free vasprintf vc-list-files verify
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
 gl_LOCAL_DIR([])
@@ -25,6 +25,7 @@ gl_MODULES([
   getpass
   gettext
   inet_pton
+  mkstemp
   mktempd
   physmem
   poll
index 239eb7a5f540ee12ac041cc43800b21be7083985..dbbaaa6299765320a7f3bccafe4534741dd78c33 100644 (file)
@@ -60,6 +60,7 @@ AC_DEFUN([gl_INIT],
   AM_GNU_GETTEXT_VERSION([0.17])
   AC_SUBST([LIBINTL])
   AC_SUBST([LTLIBINTL])
+  gl_FUNC_GETTIMEOFDAY
   gl_INET_NTOP
   gl_ARPA_INET_MODULE_INDICATOR([inet_ntop])
   gl_INET_PTON
@@ -68,6 +69,8 @@ AC_DEFUN([gl_INIT],
   gl_UNISTD_MODULE_INDICATOR([lseek])
   gl_FUNC_MALLOC_POSIX
   gl_STDLIB_MODULE_INDICATOR([malloc-posix])
+  gl_FUNC_MKSTEMP
+  gl_STDLIB_MODULE_INDICATOR([mkstemp])
   gl_HEADER_NETINET_IN
   AC_PROG_MKDIR_P
   gl_PHYSMEM
@@ -102,6 +105,7 @@ AC_DEFUN([gl_INIT],
   AC_PROG_MKDIR_P
   gl_HEADER_SYS_TIME_H
   AC_PROG_MKDIR_P
+  gl_FUNC_GEN_TEMPNAME
   gl_UNISTD_H
   gl_FUNC_VASNPRINTF
   gl_FUNC_VASPRINTF
@@ -268,10 +272,12 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/getpass.c
   lib/getpass.h
   lib/gettext.h
+  lib/gettimeofday.c
   lib/inet_ntop.c
   lib/inet_pton.c
   lib/lseek.c
   lib/malloc.c
+  lib/mkstemp.c
   lib/netinet_in.in.h
   lib/physmem.c
   lib/physmem.h
@@ -299,6 +305,8 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/sys_socket.in.h
   lib/sys_stat.in.h
   lib/sys_time.in.h
+  lib/tempname.c
+  lib/tempname.h
   lib/unistd.in.h
   lib/vasnprintf.c
   lib/vasnprintf.h
@@ -318,6 +326,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/getline.m4
   m4/getpass.m4
   m4/gettext.m4
+  m4/gettimeofday.m4
   m4/glibc2.m4
   m4/glibc21.m4
   m4/gnulib-common.m4
@@ -341,6 +350,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/longlong.m4
   m4/lseek.m4
   m4/malloc.m4
+  m4/mkstemp.m4
   m4/netinet_in_h.m4
   m4/nls.m4
   m4/onceonly.m4
@@ -371,6 +381,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/sys_socket_h.m4
   m4/sys_stat_h.m4
   m4/sys_time_h.m4
+  m4/tempname.m4
   m4/uintmax_t.m4
   m4/unistd_h.m4
   m4/vasnprintf.m4
@@ -389,6 +400,7 @@ AC_DEFUN([gl_FILE_LIST], [
   tests/test-getaddrinfo.c
   tests/test-getdelim.c
   tests/test-getline.c
+  tests/test-gettimeofday.c
   tests/test-lseek.c
   tests/test-lseek.sh
   tests/test-netinet_in.c
index a57e4c6cba52f4fd47140e7085cf06b0f19620fd..a72cd2383ca0157c01c06642b4aea7aeff996aaa 100644 (file)
@@ -6,7 +6,7 @@ dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_INET_PTON],
 [
-  dnl Persuade Solaris <arpa/inet.h> to declare inet_ntop.
+  dnl Persuade Solaris <arpa/inet.h> to declare inet_pton.
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
 
   AC_REQUIRE([gl_ARPA_INET_H_DEFAULTS])
diff --git a/gnulib/m4/mkstemp.m4 b/gnulib/m4/mkstemp.m4
new file mode 100644 (file)
index 0000000..20d8a1b
--- /dev/null
@@ -0,0 +1,56 @@
+#serial 17
+
+# Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# On some hosts (e.g., HP-UX 10.20, SunOS 4.1.4, Solaris 2.5.1), mkstemp has a
+# silly limit that it can create no more than 26 files from a given template.
+# Other systems lack mkstemp altogether.
+# On OSF1/Tru64 V4.0F, the system-provided mkstemp function can create
+# only 32 files per process.
+# On systems like the above, arrange to use the replacement function.
+AC_DEFUN([gl_FUNC_MKSTEMP],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_REQUIRE([AC_SYS_LARGEFILE])
+
+  AC_CACHE_CHECK([for working mkstemp],
+    [gl_cv_func_working_mkstemp],
+    [
+      mkdir conftest.mkstemp
+      AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM(
+         [AC_INCLUDES_DEFAULT],
+         [[int i;
+           off_t large = (off_t) 4294967295u;
+           if (large < 0)
+             large = 2147483647;
+           for (i = 0; i < 70; i++)
+             {
+               char templ[] = "conftest.mkstemp/coXXXXXX";
+               int (*mkstemp_function) (char *) = mkstemp;
+               int fd = mkstemp_function (templ);
+               if (fd < 0 || lseek (fd, large, SEEK_SET) != large)
+                 return 1;
+               close (fd);
+             }
+           return 0;]])],
+       [gl_cv_func_working_mkstemp=yes],
+       [gl_cv_func_working_mkstemp=no],
+       [gl_cv_func_working_mkstemp=no])
+      rm -rf conftest.mkstemp
+    ])
+
+  if test $gl_cv_func_working_mkstemp != yes; then
+    REPLACE_MKSTEMP=1
+    AC_LIBOBJ([mkstemp])
+    gl_PREREQ_MKSTEMP
+  fi
+])
+
+# Prerequisites of lib/mkstemp.c.
+AC_DEFUN([gl_PREREQ_MKSTEMP],
+[
+])
diff --git a/gnulib/m4/tempname.m4 b/gnulib/m4/tempname.m4
new file mode 100644 (file)
index 0000000..4c44d37
--- /dev/null
@@ -0,0 +1,22 @@
+#serial 3
+
+# Copyright (C) 2006-2007 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# glibc provides __gen_tempname as a wrapper for mk[ds]temp.  Expose
+# it as a public API, and provide it on systems that are lacking.
+AC_DEFUN([gl_FUNC_GEN_TEMPNAME],
+[
+  AC_REQUIRE([AC_SYS_LARGEFILE])
+
+  AC_LIBOBJ([tempname])
+  gl_PREREQ_TEMPNAME
+])
+
+# Prerequisites of lib/tempname.c.
+AC_DEFUN([gl_PREREQ_TEMPNAME],
+[
+  :
+])
index 6692c7f47ed0e84f34c27bcbc8504c607f0fe741..6995840b17e0828d281f9fd4b79c954eebf337ff 100644 (file)
@@ -114,6 +114,15 @@ EXTRA_DIST += test-getline.c
 
 ## end   gnulib module getline-tests
 
+## begin gnulib module gettimeofday-tests
+
+TESTS += test-gettimeofday
+check_PROGRAMS += test-gettimeofday
+
+EXTRA_DIST += test-gettimeofday.c
+
+## end   gnulib module gettimeofday-tests
+
 ## begin gnulib module intprops
 
 
diff --git a/gnulib/tests/test-gettimeofday.c b/gnulib/tests/test-gettimeofday.c
new file mode 100644 (file)
index 0000000..892b188
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005, 2007 Free Software Foundation
+ * Written by Jim Meyering.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <stdio.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+  time_t t = 0;
+  struct tm *lt;
+  struct tm saved_lt;
+  struct timeval tv;
+  lt = localtime (&t);
+  saved_lt = *lt;
+  gettimeofday (&tv, NULL);
+  if (memcmp (lt, &saved_lt, sizeof (struct tm)) != 0)
+    {
+      fprintf (stderr, "gettimeofday still clobbers the localtime buffer!\n");
+      return 1;
+    }
+  else
+    {
+      return 0;
+    }
+}