Public feed #532570

Stuff

public c v1 · immutable
Raw Edit
·published 2007-06-03 05:34 UTC
rendered paste body
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# if HAVE_GETTIMEOFDAY || _LIBC  {    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#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 = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);          break;        case __GT_BIGFILE:          fd = __open64 (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;}