text: /*
   * Copyright (C) by Argonne National Laboratory
   *     See COPYRIGHT in top-level directory
   */
  
  /* for ATTRIBUTE */
  #include "mpichconf.h"
  #include "mpl.h"
  
  #include <errno.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <unistd.h>
  
  /* here to prevent "has no symbols" warnings from ranlib on OS X */
  static int dummy ATTRIBUTE((unused)) MPL_USED = 0;
  
  #if !defined (HAVE_MKSTEMP) || !HAVE_MKSTEMP
  
  #warning The mkstemp function is not provided in the standard library.
  #warning Using a possibly insecure replacement function.
  
  #if !defined (HAVE_RAND) || !HAVE_RAND
  static notrand = 0;
  #define srand(x) notrand = x
  #define rand() (++notrand)
  #endif
  
  #define MAX_TRIES 100 /* max number of filenames we try before giving up */
  #define NUM_XS 6 /* number of X's in the template */
  
  /* replaces NUM_XS characters in xs with random characters
     xs must be at least NUM_XS chars long */
  static void randchar (char xs[])
  {
      char chararray[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
      int i;
      
      for (i = 0; i < NUM_XS; ++i)
          xs[i] = chararray[rand() % (sizeof(chararray) - 1)];
  }
  
  
  int mkstemp (char *template)
  {
      int fd;
      unsigned int seed = (unsigned int) getpid(); /* can probably use something better */
      char *X; /* points to the XXXXXX substring in template */
      int i;
      
      srand (seed);
  
      /* find the end of the template string */
      X = template;
      while (*X)
          ++X;
  
      /* back up NUM_XS characters and check to make sure they're all 'X' */
      for (i = 0 ; i < NUM_XS; ++i)
      {
          --X;
          if (X < template || *X != 'X')
          {
              errno = EINVAL;
              return -1;
          }
      }
      
      for (i = 0; i < MAX_TRIES; ++i)
      {
          randchar (X);
          fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
          if (fd != -1)
              return fd;
      }
  
      errno = EEXIST;
      return -1;
  }
  #endif
  