Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * tmpname.c
  3.  * Original Author:     G. Haley
  4.  */
  5. /*
  6. FUNCTION
  7. <<tmpnam>>, <<tempnam>>---name for a temporary file
  8.  
  9. INDEX
  10.         tmpnam
  11. INDEX
  12.         tempnam
  13. INDEX
  14.         _tmpnam_r
  15. INDEX
  16.         _tempnam_r
  17.  
  18. ANSI_SYNOPSIS
  19.         #include <stdio.h>
  20.         char *tmpnam(char *<[s]>);
  21.         char *tempnam(char *<[dir]>, char *<[pfx]>);
  22.         char *_tmpnam_r(struct _reent *<[reent]>, char *<[s]>);
  23.         char *_tempnam_r(struct _reent *<[reent]>, char *<[dir]>, char *<[pfx]>);
  24.  
  25. TRAD_SYNOPSIS
  26.         #include <stdio.h>
  27.         char *tmpnam(<[s]>)
  28.         char *<[s]>;
  29.  
  30.         char *tempnam(<[dir]>, <[pfx]>)
  31.         char *<[dir]>;
  32.         char *<[pfx]>;
  33.  
  34.         char *_tmpnam_r(<[reent]>, <[s]>)
  35.         struct _reent *<[reent]>;
  36.         char *<[s]>;
  37.  
  38.         char *_tempnam_r(<[reent]>, <[dir]>, <[pfx]>)
  39.         struct *<[reent]>;
  40.         char *<[dir]>;
  41.         char *<[pfx]>;
  42.  
  43. DESCRIPTION
  44. Use either of these functions to generate a name for a temporary file.
  45. The generated name is guaranteed to avoid collision with other files
  46. (for up to <<TMP_MAX>> calls of either function).
  47.  
  48. <<tmpnam>> generates file names with the value of <<P_tmpdir>>
  49. (defined in `<<stdio.h>>') as the leading directory component of the path.
  50.  
  51. You can use the <<tmpnam>> argument <[s]> to specify a suitable area
  52. of memory for the generated filename; otherwise, you can call
  53. <<tmpnam(NULL)>> to use an internal static buffer.
  54.  
  55. <<tempnam>> allows you more control over the generated filename: you
  56. can use the argument <[dir]> to specify the path to a directory for
  57. temporary files, and you can use the argument <[pfx]> to specify a
  58. prefix for the base filename.
  59.  
  60. If <[dir]> is <<NULL>>, <<tempnam>> will attempt to use the value of
  61. environment variable <<TMPDIR>> instead; if there is no such value,
  62. <<tempnam>> uses the value of <<P_tmpdir>> (defined in `<<stdio.h>>').
  63.  
  64. If you don't need any particular prefix to the basename of temporary
  65. files, you can pass <<NULL>> as the <[pfx]> argument to <<tempnam>>.
  66.  
  67. <<_tmpnam_r>> and <<_tempnam_r>> are reentrant versions of <<tmpnam>>
  68. and <<tempnam>> respectively.  The extra argument <[reent]> is a
  69. pointer to a reentrancy structure.
  70.  
  71. WARNINGS
  72. The generated filenames are suitable for temporary files, but do not
  73. in themselves make files temporary.  Files with these names must still
  74. be explicitly removed when you no longer want them.
  75.  
  76. If you supply your own data area <[s]> for <<tmpnam>>, you must ensure
  77. that it has room for at least <<L_tmpnam>> elements of type <<char>>.
  78.  
  79. RETURNS
  80. Both <<tmpnam>> and <<tempnam>> return a pointer to the newly
  81. generated filename.
  82.  
  83. PORTABILITY
  84. ANSI C requires <<tmpnam>>, but does not specify the use of
  85. <<P_tmpdir>>.  The System V Interface Definition (Issue 2) requires
  86. both <<tmpnam>> and <<tempnam>>.
  87.  
  88. Supporting OS subroutines required: <<close>>,  <<fstat>>, <<getpid>>,
  89. <<isatty>>, <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
  90.  
  91. The global pointer <<environ>> is also required.
  92. */
  93.  
  94. #include <_ansi.h>
  95. #include <reent.h>
  96. #include <stdio.h>
  97. #include <stdlib.h>
  98. #include <string.h>
  99. #include <fcntl.h>
  100. #include <reent.h>
  101. #include <errno.h>
  102.  
  103. /* Try to open the file specified, if it can't be opened then try
  104.    another one.  Return nonzero if successful, otherwise zero.  */
  105.  
  106. static int
  107. _DEFUN(worker, (ptr, result, part1, part2, part3, part4),
  108.        struct _reent *ptr _AND
  109.        char *result       _AND
  110.        _CONST char *part1 _AND
  111.        _CONST char *part2 _AND
  112.        int part3          _AND
  113.        int *part4)
  114. {
  115.   /*  Generate the filename and make sure that there isn't one called
  116.       it already.  */
  117.  
  118.   while (1)
  119.     {
  120.       int t;
  121.       _sprintf_r (ptr, result, "%s/%s%x.%x", part1, part2, part3, *part4);
  122.       (*part4)++;
  123.       t = _open_r (ptr, result, O_RDONLY, 0);
  124.       if (t == -1)
  125.         {
  126.           if (ptr->_errno == ENOSYS)
  127.             {
  128.               result[0] = '\0';
  129.               return 0;
  130.             }
  131.           break;
  132.         }
  133.       _close_r (ptr, t);
  134.     }
  135.   return 1;
  136. }
  137.  
  138. char *
  139. _DEFUN(_tmpnam_r, (p, s),
  140.        struct _reent *p _AND
  141.        char *s)
  142. {
  143.   char *result;
  144.   int pid;
  145.  
  146.   if (s == NULL)
  147.     {
  148.       /* ANSI states we must use an internal static buffer if s is NULL */
  149.       _REENT_CHECK_EMERGENCY(p);
  150.       result = _REENT_EMERGENCY(p);
  151.     }
  152.   else
  153.     {
  154.       result = s;
  155.     }
  156.   pid = _getpid_r (p);
  157.  
  158.   if (worker (p, result, P_tmpdir, "t", pid, &p->_inc))
  159.     {
  160.       p->_inc++;
  161.       return result;
  162.     }
  163.  
  164.   return NULL;
  165. }
  166.  
  167. char *
  168. _DEFUN(_tempnam_r, (p, dir, pfx),
  169.        struct _reent *p _AND
  170.        _CONST char *dir _AND
  171.        _CONST char *pfx)
  172. {
  173.   char *filename;
  174.   int length;
  175.   _CONST char *prefix = (pfx) ? pfx : "";
  176.   if (dir == NULL && (dir = getenv ("TMPDIR")) == NULL)
  177.     dir = P_tmpdir;
  178.  
  179.   /* two 8 digit numbers + . / */
  180.   length = strlen (dir) + strlen (prefix) + (4 * sizeof (int)) + 2 + 1;
  181.  
  182.   filename = _malloc_r (p, length);
  183.   if (filename)
  184.     {
  185.       if (! worker (p, filename, dir, prefix,
  186.                     _getpid_r (p) ^ (int) (_POINTER_INT) p, &p->_inc))
  187.         return NULL;
  188.     }
  189.   return filename;
  190. }
  191.  
  192. #ifndef _REENT_ONLY
  193.  
  194. char *
  195. _DEFUN(tempnam, (dir, pfx),
  196.        _CONST char *dir _AND
  197.        _CONST char *pfx)
  198. {
  199.   return _tempnam_r (_REENT, dir, pfx);
  200. }
  201.  
  202. char *
  203. _DEFUN(tmpnam, (s),
  204.        char *s)
  205. {
  206.   return _tmpnam_r (_REENT, s);
  207. }
  208.  
  209. #endif
  210.