summaryrefslogtreecommitdiffstats
path: root/private/crt32/stdio/tempnam.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/stdio/tempnam.c')
-rw-r--r--private/crt32/stdio/tempnam.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/private/crt32/stdio/tempnam.c b/private/crt32/stdio/tempnam.c
new file mode 100644
index 000000000..4539ba870
--- /dev/null
+++ b/private/crt32/stdio/tempnam.c
@@ -0,0 +1,262 @@
+/***
+*tempnam.c - generate unique file name
+*
+* Copyright (c) 1986-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+*
+*Revision History:
+* ??-??-?? TC initial version
+* 04-17-86 JMB changed directory of last resort from \tmp to tmp.
+* eliminated use of L_tmpnam (it was incoorectly defined
+* in stdio.h and should not be used in tempnam; see
+* System V definition of tempnam.
+* 04-23-86 TC changed last try directory from tmp to current directory
+* 04-29-86 JMB bug fix: pfxlength was being set from strlen(pfx)
+* even if pfx was NULL. Fixed to set pfxlength to zero
+* if pfx is NULL, strlen(pfx) otherwise.
+* 05-28-86 TC changed stat's to access's, and optimized code a bit
+* 12-01-86 JMB added support for Kanji file names until KANJI switch
+* 12-15-86 JMB free malloced memory if (++_tmpoff == first)
+* 07-15-87 JCR Re-init _tempoff based on length of pfx (fixes infinate
+* loop bug; also, tempnam() now uses _tempoff instead of
+* _tmpoff (used by tmpnam()).
+* 10-16-87 JCR Fixed bug in _tempoff re-init code if pfx is NULL.
+* 11-09-87 JCR Multi-thread version
+* 12-11-87 JCR Added "_LOAD_DS" to declaration
+* 05-27-88 PHG Merged DLL and normal versions
+* 06-09-89 GJF Propagated MT's change of 05-17-89 (Kanji)
+* 02-16-90 GJF Fixed copyright and indents
+* 03-19-90 GJF Replaced _LOAD_DS and _CALLTYPE1 and added #include
+* <cruntime.h>.
+* 03-26-90 GJF Added #include <io.h>.
+* 08-13-90 SBM Compiles cleanly with -W3, replaced explicit register
+* declarations by REGn references
+* 10-03-90 GJF New-style function declarator.
+* 01-21-91 GJF ANSI naming.
+* 08-19-91 JCR Allow quotes in TMP variable path
+* 08-27-91 JCR ANSI naming
+* 08-25-92 GJF Don't build for POSIX.
+* 11-30-92 KRS Generalize KANJI support to MBCS. Port 16-bit bug fix.
+*
+*******************************************************************************/
+
+#ifndef _POSIX_
+
+#include <cruntime.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <internal.h>
+#include <os2dll.h>
+
+#ifdef _MBCS
+#include <mbstring.h>
+#endif
+
+static char * _stripquote (char *);
+
+/***
+*char *_tempnam(dir, prefix) - create unique file name
+*
+*Purpose:
+* Create a file name that is unique in the specified directory.
+* The semantics of directory specification is as follows:
+* Use the directory specified by the TMP environment variable
+* if that exists, else use the dir argument if non-NULL, else
+* use _P_tmpdir if that directory exists, else use the current
+* working directory), else return NULL.
+*
+*Entry:
+* char *dir - directory to be used for temp file if TMP env var
+* not set
+* char *prefix - user provided prefix for temp file name
+*
+*Exit:
+* returns ptr to constructed file name if successful
+* returns NULL if unsuccessful
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+char * _CALLTYPE1 _tempnam (
+ char *dir,
+ char *pfx
+ )
+{
+ REG1 char *ptr;
+ REG2 unsigned int pfxlength=0;
+ char *s;
+ char *pfin;
+ unsigned int first;
+ char * qptr = NULL; /* ptr to TMP path with quotes stripped out */
+
+ /* try TMP path */
+ if ( ( ptr = getenv( "TMP" ) ) && ( _access( ptr, 0 ) != -1 ) )
+ dir = ptr;
+
+ /* try stripping quotes out of TMP path */
+ else if ( (ptr != NULL) && (qptr = _stripquote(ptr)) &&
+ (_access(qptr, 0) != -1 ) )
+ dir = qptr;
+
+ /* TMP path not available, use alternatives */
+ else if (!( dir != NULL && ( _access( dir, 0 ) != -1 ) ) )
+ /* do not "simplify" this depends on side effects!! */
+ {
+ free(qptr); /* free buffer, if non-NULL */
+ if ( _access( _P_tmpdir, 0 ) != -1 )
+ dir = _P_tmpdir;
+ else
+ dir = ".";
+ }
+
+
+ if (pfx)
+ pfxlength = strlen(pfx);
+ if ( ( s = malloc(strlen(dir) + pfxlength + 8 ) ) == NULL )
+ /* the 8 above allows for a backslash, 6 char temp string and
+ a null terminator */
+ {
+ goto done2;
+ }
+ *s = '\0';
+ strcat( s, dir );
+ pfin = &(dir[ strlen( dir ) - 1 ]);
+#ifdef _MBCS
+ if (*pfin == '\\') {
+ if (pfin != _mbsrchr(dir,'\\'))
+ /* *pfin is second byte of a double-byte char */
+ strcat( s, "\\" );
+ }
+ else if (*pfin != '/')
+ strcat( s, "\\" );
+#else
+ if ( ( *pfin != '\\' ) && ( *pfin != '/' ) )
+ {
+ strcat( s, "\\" );
+ }
+#endif
+ if ( pfx != NULL )
+ {
+ strcat( s, pfx );
+ }
+ ptr = &s[strlen( s )];
+
+ /*
+ Re-initialize _tempoff if necessary. If we don't re-init _tempoff, we
+ can get into an infinate loop (e.g., (a) _tempoff is a big number on
+ entry, (b) prefix is a long string (e.g., 8 chars) and all tempfiles
+ with that prefix exist, (c) _tempoff will never equal first and we'll
+ loop forever).
+
+ [NOTE: To avoid a conflict that causes the same bug as that discussed
+ above, _tempnam() uses _tempoff; tmpnam() uses _tmpoff]
+ */
+
+ _mlock(_TMPNAM_LOCK); /* Lock access to _old_pfxlen and _tempoff */
+
+ if (_old_pfxlen < pfxlength)
+ _tempoff = 1;
+ _old_pfxlen = pfxlength;
+
+ first = _tempoff;
+
+ do {
+ if ( ++_tempoff == first ) {
+ free(s);
+ s = NULL;
+ goto done1;
+ }
+ _itoa( _tempoff, ptr, 10 );
+ if ( strlen( ptr ) + pfxlength > 8 )
+ {
+ *ptr = '\0';
+ _tempoff = 0;
+ }
+ }
+ while ( (_access( s, 0 ) == 0 ) || (errno == EACCES) );
+
+
+ /* Common return */
+done1:
+ _munlock(_TMPNAM_LOCK); /* release tempnam lock */
+done2:
+ free(qptr); /* free temp ptr, if non-NULL */
+ return(s);
+}
+
+
+
+/***
+*_stripquote() - Strip quotes out of a string
+*
+*Purpose:
+* This routine strips quotes out of a string. This is necessary
+* in the case where a file/path name has embedded quotes (i.e.,
+* new file system.)
+*
+* For example,
+* c:\tmp\"a b c"\d --> c:\tmp\a b d\d
+*
+* NOTE: This routine makes a copy of the string since it may be
+* passed a pointer to an environment variable that shouldn't be
+* changed. It is up to the caller to free up the memory (if the
+* return value is non-NULL).
+*
+*Entry:
+* char * ptr = pointer to string
+*
+*Exit:
+* char * ptr = pointer to copy of string with quotes gone.
+* NULL = no quotes in string.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+char * _stripquote (src)
+char * src;
+{
+ char * dst;
+ char * ret;
+ unsigned int q = 0;
+
+
+ /* get a buffer for the new string */
+
+ if ((dst = malloc(strlen(src)+1)) == NULL)
+ return(NULL);
+
+ /* copy the string stripping out the quotes */
+
+ ret = dst; /* save base ptr */
+
+ while (*src) {
+
+ if (*src == '\"') {
+ src++; q++;
+ }
+ else
+ *dst++ = *src++;
+ }
+
+ if (q) {
+ *dst = '\0'; /* final nul */
+ return(ret);
+ }
+ else {
+ free(ret);
+ return(NULL);
+ }
+
+}
+
+
+#endif /* _POSIX_ */