Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
5.1 KiB

  1. /***
  2. *mktemp.c - create a unique file name
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _mktemp() - create a unique file name
  8. *
  9. *Revision History:
  10. * 06-02-86 JMB eliminated unneccesary routine exits
  11. * 05-26-87 JCR fixed bug where mktemp was incorrectly modifying
  12. * the errno value.
  13. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  14. * 07-11-88 JCR Optimized REG allocation
  15. * 03-12-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include
  16. * <cruntime.h>, removed #include <register.h> and
  17. * fixed the copyright. Also, cleaned up the formatting
  18. * a bit.
  19. * 04-04-90 GJF Added #include <process.h> and #include <io.h>. Removed
  20. * #include <sizeptr.h>.
  21. * 07-23-90 SBM Replaced <assertm.h> by <assert.h>
  22. * 08-13-90 SBM Compiles cleanly with -W3
  23. * 09-28-90 GJF New-style function declarator.
  24. * 01-16-91 GJF ANSI naming.
  25. * 11-30-92 KRS Ported _MBCS code from 16-bit tree.
  26. * 06-18-93 KRS MBCS-only bug fix ported from 16-bit tree.
  27. * 08-03-93 KRS Call _ismbstrail instead of isdbcscode.
  28. * 11-01-93 CFW Enable Unicode variant.
  29. * 02-21-94 SKS Use ThreadID instead of ProcessID in multi-thread libs.
  30. * 04-11-94 CFW Fix first X handling, cycle 'a'-'z'.
  31. * 02-06-95 CFW assert -> _ASSERTE.
  32. * 02-15-95 GJF Appended Mac version of source file (somewhat cleaned
  33. * up), with appropriate #ifdef-s.
  34. * 03-28-96 GJF Detab-ed. Also, replaced isdbcscode with __isdbcscode.
  35. * 07-08-96 GJF Replaced defined(_WIN32) with !defined(_MAC), and
  36. * defined(_M_M68K) || defined(_M_MPPC) with
  37. * defined(_MAC). Removed obsolete REG* macros. Also,
  38. * cleaned up the format a bit.
  39. * 05-17-99 PML Remove all Macintosh support.
  40. *
  41. *******************************************************************************/
  42. #include <cruntime.h>
  43. #include <stdio.h>
  44. #include <io.h>
  45. #include <process.h>
  46. #include <errno.h>
  47. #include <dbgint.h>
  48. #include <stddef.h>
  49. #ifdef _MBCS
  50. #include <mbctype.h>
  51. #include <mbdata.h>
  52. #endif
  53. #include <tchar.h>
  54. /***
  55. *_TSCHAR *_mktemp(template) - create a unique file name
  56. *
  57. *Purpose:
  58. * given a template of the form "fnamXXXXXX", insert number on end
  59. * of template, insert unique letter if needed until unique filename
  60. * found or run out of letters. The number is generated from the Win32
  61. * Process ID for single-thread libraries, or the Win32 Thread ID for
  62. * multi-thread libraries.
  63. *
  64. *Entry:
  65. * _TSCHAR *template - template of form "fnamXXXXXX"
  66. *
  67. *Exit:
  68. * return pointer to modifed template
  69. * returns NULL if template malformed or no more unique names
  70. *
  71. *Exceptions:
  72. *
  73. *******************************************************************************/
  74. _TSCHAR * __cdecl _tmktemp (
  75. _TSCHAR *template
  76. )
  77. {
  78. _TSCHAR *string = template;
  79. unsigned number;
  80. int letter = _T('a');
  81. int xcount = 0;
  82. int olderrno;
  83. _ASSERTE(template != NULL);
  84. _ASSERTE(*template != _T('\0'));
  85. /*
  86. * The Process ID is not a good choice in multi-threaded programs
  87. * because of the likelihood that two threads might call mktemp()
  88. * almost simultaneously, thus getting the same temporary name.
  89. * Instead, the Win32 Thread ID is used, because it is unique across
  90. * all threads in all processes currently running.
  91. *
  92. * Note, however, that unlike *NIX process IDs, which are not re-used
  93. * until all values up to 32K have been used, Win32 process IDs are
  94. * re-used and tend to always be relatively small numbers. Same for
  95. * thread IDs.
  96. */
  97. #ifdef _MT
  98. number = __threadid();
  99. #else
  100. number = _getpid();
  101. #endif
  102. while (*string)
  103. string++;
  104. /* replace last five X's */
  105. #ifdef _MBCS
  106. while ((--string>=template) && (!_ismbstrail(template,string))
  107. && (*string == 'X') && xcount < 5)
  108. #else
  109. while (*--string == _T('X') && xcount < 5)
  110. #endif
  111. {
  112. xcount++;
  113. *string = (_TSCHAR)((number % 10) + '0');
  114. number /= 10;
  115. }
  116. /* too few X's ? */
  117. if (*string != _T('X') || xcount < 5)
  118. return(NULL);
  119. /* set first X */
  120. *string = letter++;
  121. olderrno = errno; /* save current errno */
  122. errno = 0; /* make sure errno isn't EACCESS */
  123. /* check all the files 'a'-'z' */
  124. while ((_taccess(template,0) == 0) || (errno == EACCES))
  125. /* while file exists */
  126. {
  127. errno = 0;
  128. if (letter == _T('z') + 1) {
  129. errno = olderrno;
  130. return(NULL);
  131. }
  132. *string = (_TSCHAR)letter++;
  133. }
  134. errno = olderrno;
  135. return(template);
  136. }