util/mkrtemp.c
/*
 *
 * mkrtemp -- make a unique temportary filename that is hard to guess,
 * and, optionally, open it using securely: O_CREAT|O_EXCL|O_RDWR, 0600.
 * This should be an improvement over mktmp and mkstmp because of the use
 * of usec of gettimeofday() to make up the filename -- harder to guess.
 * If you want to use a random number generater instead, set the environment
 * variable MTRTEMP_RAND to "true".
 *
 * The routine also allows for both a prefix and suffix to be specified,
 * so that you can create files with extensions. Either of these can be NULL.
 *
 */
- make a unique temportary filename that is hard to guess,
and, optionally, open it using securely: O_CREAT|O_EXCL|O_RDWR, 0600.
This should be an improvement over mktmp and mkstmp because of the use
of usec of gettimeofday() to make up the filename -- harder to guess.
If you want to use a random number generater instead, set the environment
variable MTRTEMP_RAND to "true".

The routine also allows for both a prefix and suffix to be specified,
so that you can create files with extensions. Either of these can be NULL.
- make a unique temportary filename that is hard to guess and optionally open it using securely : O_CREAT|O_EXCL|O_RDWR 0600 . This should be an improvement over mktmp and mkstmp because of the use of usec of gettimeofday () to make up the filename -- harder to guess . If you want to use a random number generater instead set the environment variable MTRTEMP_RAND to " true " . The routine also allows for both a prefix and suffix to be specified so that you can create files with extensions . Either of these can be NULL .
int mkrtemp(char *prefix, char *suffix, char *path, int len, int doopen){
  char *s;
  int fd;
  long lval;
  struct stat sbuf;
  struct timeval tv;
  static int _method=0;
  *path = '\0';
  if( len <=0 ){
    return -1;
  }
  if( prefix && *prefix ){
    int bad=0;
    char *xprefix=xstrdup(prefix);
    for(s=xprefix; *s; s++){
      ;
    }
    for(; s>=xprefix ; s--){
      if( (*s == '/') || (*s == '\\') ){
	*s = '\0';
	if( stat(xprefix, &sbuf) ){
	  bad = -1;
	}
	else if( !S_ISDIR(sbuf.st_mode) ){
	  errno = ENOTDIR;
	  bad = -1;
	}
	break;
      }
    }
    free(xprefix);
    if( bad )
      return -1;
  }
  if( !_method ){
    _method = 1;
    if( (s=(char *)getenv("MKRTEMP_RAND")) && istrue(s) ){
      _method = 2;
    }
    gettimeofday(&tv, NULL);
    switch(_method){
    case 1:
      break;
    case 2:
      srand48(tv.tv_sec+tv.tv_usec);
      break;
    }
  }
  lval = 0;
  while( 1 ){
    switch(_method){
    case 1:
      gettimeofday(&tv, NULL);
      if( lval == tv.tv_usec ){
	lval /= 2;
      } else{
	lval = tv.tv_usec;
      }
      break;
    case 2:
      lval = lrand48();
      break;
    default:
      return -1;
    }
    snprintf(path, len, "%s%ld%s", 
	     (prefix?prefix:""), lval, (suffix?suffix:""));
    if( doopen ){
      if( (fd=open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0){
	return fd;
      }
      if (errno != EEXIST){
	return -1;
      }
    } else if( lstat(path, &sbuf) ){
      return errno==ENOENT ? 0 : -1;
    }
  }
}
int mkrtemp ( char * prefix , char * suffix , char * path , int len , int doopen ) { char * s ; int fd ; long lval ; struct stat sbuf ; struct timeval tv ; static int _method = 0 ; * path = ' \0 ' ; if ( len <= 0 ) { return -1 ; } if ( prefix && * prefix ) { int bad = 0 ; char * xprefix = xstrdup ( prefix ) ; for ( s = xprefix ; * s ; s ++ ) { ; } for ( ; s >= xprefix ; s -- ) { if ( ( * s == ' ' ) || ( * s == ' \\ ' ) ) { * s = ' \0 ' ; if ( stat ( xprefix , & sbuf ) ) { bad = -1 ; } else if ( ! S_ISDIR ( sbuf . st_mode ) ) { errno = ENOTDIR ; bad = -1 ; } break ; } } free ( xprefix ) ; if ( bad ) return -1 ; } if ( ! _method ) { _method = 1 ; if ( ( s = ( char * ) getenv ( " " ) ) && istrue ( s ) ) { _method = 2 ; } gettimeofday ( & tv , NULL ) ; switch ( _method ) { case 1 : break ; case 2 : srand48 ( tv . tv_sec + tv . tv_usec ) ; break ; } } lval = 0 ; while ( 1 ) { switch ( _method ) { case 1 : gettimeofday ( & tv , NULL ) ; if ( lval == tv . tv_usec ) { lval /= 2 ; } else { lval = tv . tv_usec ; } break ; case 2 : lval = lrand48 ( ) ; break ; default : return -1 ; } snprintf ( path , len , " " , ( prefix ? prefix : " " ) , lval , ( suffix ? suffix : " " ) ) ; if ( doopen ) { if ( ( fd = open ( path , O_CREAT | O_EXCL | O_RDWR , 0600 ) ) >= 0 ) { return fd ; } if ( errno != EEXIST ) { return -1 ; } } else if ( lstat ( path , & sbuf ) ) { return errno == ENOENT ? 0 : -1 ; } } }
mkrtemp -- make a unique temportary filename that is hard to guess,
 and, optionally, open it using securely: O_CREAT|O_EXCL|O_RDWR, 0600.
mkrtemp -- make a unique temportary filename that is hard to guess and optionally open it using securely : O_CREAT|O_EXCL|O_RDWR 0600 .
/* clear the buffer */ /* check validity of the target directory, if necessary */ /* initialize method */ /* assume gettimeofday() usecs */ /* but allow for using RNG */ /* main loop -- make up a new file name and check for non-existence */ /* avoid repeated checks on same value of lval */