source: trunk/libs/newlib/src/newlib/libc/stdio/tmpnam.c @ 567

Last change on this file since 567 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

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