Subversion Repositories Kolibri OS

Rev

Rev 5217 | 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. #elif HAVE_TIME_H
  39. #include <time.h>
  40. #endif
  41. #include "ansidecl.h"
  42.  
  43. /* We need to provide a type for gcc_uint64_t.  */
  44. #ifdef __GNUC__
  45. __extension__ typedef unsigned long long gcc_uint64_t;
  46. #else
  47. typedef unsigned long gcc_uint64_t;
  48. #endif
  49.  
  50. #ifndef TMP_MAX
  51. #define TMP_MAX 16384
  52. #endif
  53.  
  54. #ifndef O_BINARY
  55. # define O_BINARY 0
  56. #endif
  57.  
  58. /*
  59.  
  60. @deftypefn Replacement int mkstemps (char *@var{pattern}, int @var{suffix_len})
  61.  
  62. Generate a unique temporary file name from @var{pattern}.
  63. @var{pattern} has the form:
  64.  
  65. @example
  66.    @var{path}/ccXXXXXX@var{suffix}
  67. @end example
  68.  
  69. @var{suffix_len} tells us how long @var{suffix} is (it can be zero
  70. length).  The last six characters of @var{pattern} before @var{suffix}
  71. must be @samp{XXXXXX}; they are replaced with a string that makes the
  72. filename unique.  Returns a file descriptor open on the file for
  73. reading and writing.
  74.  
  75. @end deftypefn
  76.  
  77. */
  78.  
  79. int
  80. mkstemps (char *pattern, int suffix_len)
  81. {
  82.   static const char letters[]
  83.     = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  84.   static gcc_uint64_t value;
  85. #ifdef HAVE_GETTIMEOFDAY
  86.   struct timeval tv;
  87. #endif
  88.   char *XXXXXX;
  89.   size_t len;
  90.   int count;
  91.  
  92.   len = strlen (pattern);
  93.  
  94.   if ((int) len < 6 + suffix_len
  95.       || strncmp (&pattern[len - 6 - suffix_len], "XXXXXX", 6))
  96.     {
  97.       return -1;
  98.     }
  99.  
  100.   XXXXXX = &pattern[len - 6 - suffix_len];
  101.  
  102. #ifdef HAVE_GETTIMEOFDAY
  103.   /* Get some more or less random data.  */
  104.   gettimeofday (&tv, NULL);
  105.   value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; // ^ getpid ();
  106. #else
  107.   value += 1;//getpid ();
  108. #endif
  109.  
  110.   for (count = 0; count < TMP_MAX; ++count)
  111.     {
  112.       gcc_uint64_t v = value;
  113.       int fd;
  114.  
  115.       /* Fill in the random bits.  */
  116.       XXXXXX[0] = letters[v % 62];
  117.       v /= 62;
  118.       XXXXXX[1] = letters[v % 62];
  119.       v /= 62;
  120.       XXXXXX[2] = letters[v % 62];
  121.       v /= 62;
  122.       XXXXXX[3] = letters[v % 62];
  123.       v /= 62;
  124.       XXXXXX[4] = letters[v % 62];
  125.       v /= 62;
  126.       XXXXXX[5] = letters[v % 62];
  127.  
  128.       fd = open (pattern, O_BINARY|O_RDWR|O_CREAT|O_EXCL, 0600);
  129.       if (fd >= 0)
  130.         /* The file does not exist.  */
  131.         return fd;
  132.       if (errno != EEXIST
  133. #ifdef EISDIR
  134.           && errno != EISDIR
  135. #endif
  136.          )
  137.         /* Fatal error (EPERM, ENOSPC etc).  Doesn't make sense to loop.  */
  138.         break;
  139.  
  140.       /* This is a random value.  It is only necessary that the next
  141.          TMP_MAX values generated by adding 7777 to VALUE are different
  142.          with (module 2^32).  */
  143.       value += 7777;
  144.     }
  145.  
  146.   /* We return the null string if we can't find a unique file name.  */
  147.   pattern[0] = '\0';
  148.   return -1;
  149. }
  150.