Subversion Repositories Kolibri OS

Rev

Rev 5191 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* Copyright (C) 1991, 1992, 1996, 1998, 2004 Free Software Foundation, Inc.
  2.    This file is derived from mkstemp.c from the GNU C Library.
  3.  
  4.    The GNU C Library is free software; you can redistribute it and/or
  5.    modify it under the terms of the GNU Library General Public License as
  6.    published by the Free Software Foundation; either version 2 of the
  7.    License, or (at your option) any later version.
  8.  
  9.    The GNU C Library is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.    Library General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU Library General Public
  15.    License along with the GNU C Library; see the file COPYING.LIB.  If not,
  16.    write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
  17.    Boston, MA 02110-1301, USA.  */
  18.  
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22.  
  23. #include <sys/types.h>
  24. #ifdef HAVE_STDLIB_H
  25. #include <stdlib.h>
  26. #endif
  27. #ifdef HAVE_STRING_H
  28. #include <string.h>
  29. #endif
  30. #include <errno.h>
  31. #include <stdio.h>
  32. #include <fcntl.h>
  33. #ifdef HAVE_UNISTD_H
  34. #include <unistd.h>
  35. #endif
  36. #ifdef HAVE_SYS_TIME_H
  37. #include <sys/time.h>
  38. #endif
  39. #include "ansidecl.h"
  40.  
  41. /* We need to provide a type for gcc_uint64_t.  */
  42. #ifdef __GNUC__
  43. __extension__ typedef unsigned long long gcc_uint64_t;
  44. #else
  45. typedef unsigned long gcc_uint64_t;
  46. #endif
  47.  
  48. #ifndef TMP_MAX
  49. #define TMP_MAX 16384
  50. #endif
  51.  
  52. #ifndef O_BINARY
  53. # define O_BINARY 0
  54. #endif
  55.  
  56. /*
  57.  
  58. @deftypefn Replacement int mkstemps (char *@var{pattern}, int @var{suffix_len})
  59.  
  60. Generate a unique temporary file name from @var{pattern}.
  61. @var{pattern} has the form:
  62.  
  63. @example
  64.    @var{path}/ccXXXXXX@var{suffix}
  65. @end example
  66.  
  67. @var{suffix_len} tells us how long @var{suffix} is (it can be zero
  68. length).  The last six characters of @var{pattern} before @var{suffix}
  69. must be @samp{XXXXXX}; they are replaced with a string that makes the
  70. filename unique.  Returns a file descriptor open on the file for
  71. reading and writing.
  72.  
  73. @end deftypefn
  74.  
  75. */
  76.  
  77. int
  78. mkstemps (char *pattern, int suffix_len)
  79. {
  80.   static const char letters[]
  81.     = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  82.   static gcc_uint64_t value;
  83. #ifdef HAVE_GETTIMEOFDAY
  84.   struct timeval tv;
  85. #endif
  86.   char *XXXXXX;
  87.   size_t len;
  88.   int count;
  89.  
  90.   len = strlen (pattern);
  91.  
  92.   if ((int) len < 6 + suffix_len
  93.       || strncmp (&pattern[len - 6 - suffix_len], "XXXXXX", 6))
  94.     {
  95.       return -1;
  96.     }
  97.  
  98.   XXXXXX = &pattern[len - 6 - suffix_len];
  99.  
  100. #ifdef HAVE_GETTIMEOFDAY
  101.   /* Get some more or less random data.  */
  102.   gettimeofday (&tv, NULL);
  103.   value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; // ^ getpid ();
  104. #else
  105.   value += 1;//getpid ();
  106. #endif
  107.  
  108.   for (count = 0; count < TMP_MAX; ++count)
  109.     {
  110.       gcc_uint64_t v = value;
  111.       int fd;
  112.  
  113.       /* Fill in the random bits.  */
  114.       XXXXXX[0] = letters[v % 62];
  115.       v /= 62;
  116.       XXXXXX[1] = letters[v % 62];
  117.       v /= 62;
  118.       XXXXXX[2] = letters[v % 62];
  119.       v /= 62;
  120.       XXXXXX[3] = letters[v % 62];
  121.       v /= 62;
  122.       XXXXXX[4] = letters[v % 62];
  123.       v /= 62;
  124.       XXXXXX[5] = letters[v % 62];
  125.  
  126.       fd = open (pattern, O_BINARY|O_RDWR|O_CREAT|O_EXCL, 0600);
  127.       if (fd >= 0)
  128.         /* The file does not exist.  */
  129.         return fd;
  130.       if (errno != EEXIST
  131. #ifdef EISDIR
  132.           && errno != EISDIR
  133. #endif
  134.          )
  135.         /* Fatal error (EPERM, ENOSPC etc).  Doesn't make sense to loop.  */
  136.         break;
  137.  
  138.       /* This is a random value.  It is only necessary that the next
  139.          TMP_MAX values generated by adding 7777 to VALUE are different
  140.          with (module 2^32).  */
  141.       value += 7777;
  142.     }
  143.  
  144.   /* We return the null string if we can't find a unique file name.  */
  145.   pattern[0] = '\0';
  146.   return -1;
  147. }
  148.