summaryrefslogtreecommitdiffstats
path: root/funtools/util/mkrtemp.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2016-10-25 20:57:49 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2016-10-25 20:57:49 (GMT)
commitd1c4bf158203c4e8ec29fdeb83fd311e36320885 (patch)
tree15874534e282f67505ce4af5ba805a1ff70ec43e /funtools/util/mkrtemp.c
parente19a18e035dc4d0e8e215f9b452bb9ef6f58b9d7 (diff)
parent339420dd5dd874c41f6bab5808291fb4036dd022 (diff)
downloadblt-d1c4bf158203c4e8ec29fdeb83fd311e36320885.zip
blt-d1c4bf158203c4e8ec29fdeb83fd311e36320885.tar.gz
blt-d1c4bf158203c4e8ec29fdeb83fd311e36320885.tar.bz2
Merge commit '339420dd5dd874c41f6bab5808291fb4036dd022' as 'funtools'
Diffstat (limited to 'funtools/util/mkrtemp.c')
-rw-r--r--funtools/util/mkrtemp.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/funtools/util/mkrtemp.c b/funtools/util/mkrtemp.c
new file mode 100644
index 0000000..51e1130
--- /dev/null
+++ b/funtools/util/mkrtemp.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory
+ */
+
+#include <mkrtemp.h>
+
+/*
+ *
+ * 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.
+ *
+ */
+#ifdef ANSI_FUNC
+int mkrtemp(char *prefix, char *suffix, char *path, int len, int doopen)
+#else
+int mkrtemp(prefix, suffix, path, len, doopen)
+ char *prefix;
+ char *suffix;
+ char *path;
+ int len;
+ int doopen;
+#endif
+{
+ char *s;
+ int fd;
+ long lval;
+ struct stat sbuf;
+ struct timeval tv;
+ static int _method=0;
+
+ /* clear the buffer */
+ *path = '\0';
+ if( len <=0 )
+ return -1;
+
+ /* check validity of the target directory, if necessary */
+ 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;
+ }
+
+ /* initialize method */
+ if( !_method ){
+ /* assume gettimeofday() usecs */
+ _method = 1;
+ /* but allow for using RNG */
+ 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;
+ }
+ }
+
+ /* main loop -- make up a new file name and check for non-existence */
+ lval = 0;
+ while( 1 ){
+ switch(_method){
+ case 1:
+ gettimeofday(&tv, NULL);
+ /* avoid repeated checks on same value of lval */
+ 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;
+ }
+}