fixed more binutils issues (newer gcc/libc)
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / stdio / tmpnam.c
blobec346c8789325f6cd91a36d12ae4b72570a0ada9
1 /*
2 * tmpname.c
3 * Original Author: G. Haley
4 */
6 /*
7 FUNCTION
8 <<tmpnam>>, <<tempnam>>---name for a temporary file
10 INDEX
11 tmpnam
12 INDEX
13 tempnam
14 INDEX
15 _tmpnam_r
16 INDEX
17 _tempnam_r
19 ANSI_SYNOPSIS
20 #include <stdio.h>
21 char *tmpnam(char *<[s]>);
22 char *tempnam(char *<[dir]>, char *<[pfx]>);
23 char *_tmpnam_r(void *<[reent]>, char *<[s]>);
24 char *_tempnam_r(void *<[reent]>, char *<[dir]>, char *<[pfx]>);
26 TRAD_SYNOPSIS
27 #include <stdio.h>
28 char *tmpnam(<[s]>)
29 char *<[s]>;
31 char *tempnam(<[dir]>, <[pfx]>)
32 char *<[dir]>;
33 char *<[pfx]>;
35 char *_tmpnam_r(<[reent]>, <[s]>)
36 char *<[reent]>;
37 char *<[s]>;
39 char *_tempnam_r(<[reent]>, <[dir]>, <[pfx]>)
40 char *<[reent]>;
41 char *<[dir]>;
42 char *<[pfx]>;
44 DESCRIPTION
45 Use either of these functions to generate a name for a temporary file.
46 The generated name is guaranteed to avoid collision with other files
47 (for up to <<TMP_MAX>> calls of either function).
49 <<tmpnam>> generates file names with the value of <<P_tmpdir>>
50 (defined in `<<stdio.h>>') as the leading directory component of the path.
52 You can use the <<tmpnam>> argument <[s]> to specify a suitable area
53 of memory for the generated filename; otherwise, you can call
54 <<tmpnam(NULL)>> to use an internal static buffer.
56 <<tempnam>> allows you more control over the generated filename: you
57 can use the argument <[dir]> to specify the path to a directory for
58 temporary files, and you can use the argument <[pfx]> to specify a
59 prefix for the base filename.
61 If <[dir]> is <<NULL>>, <<tempnam>> will attempt to use the value of
62 environment variable <<TMPDIR>> instead; if there is no such value,
63 <<tempnam>> uses the value of <<P_tmpdir>> (defined in `<<stdio.h>>').
65 If you don't need any particular prefix to the basename of temporary
66 files, you can pass <<NULL>> as the <[pfx]> argument to <<tempnam>>.
68 <<_tmpnam_r>> and <<_tempnam_r>> are reentrant versions of <<tmpnam>>
69 and <<tempnam>> respectively. The extra argument <[reent]> is a
70 pointer to a reentrancy structure.
72 WARNINGS
73 The generated filenames are suitable for temporary files, but do not
74 in themselves make files temporary. Files with these names must still
75 be explicitly removed when you no longer want them.
77 If you supply your own data area <[s]> for <<tmpnam>>, you must ensure
78 that it has room for at least <<L_tmpnam>> elements of type <<char>>.
80 RETURNS
81 Both <<tmpnam>> and <<tempnam>> return a pointer to the newly
82 generated filename.
84 PORTABILITY
85 ANSI C requires <<tmpnam>>, but does not specify the use of
86 <<P_tmpdir>>. The System V Interface Definition (Issue 2) requires
87 both <<tmpnam>> and <<tempnam>>.
89 Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>,
90 <<isatty>>, <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
92 The global pointer <<environ>> is also required.
95 #include <_ansi.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>
103 /* Try to open the file specified, if it can't be opened then try
104 another one. Return nonzero if successful, otherwise zero. */
106 static int
107 worker (ptr, result, part1, part2, part3, part4)
108 struct _reent *ptr;
109 char *result;
110 _CONST char *part1;
111 _CONST char *part2;
112 int part3;
113 int *part4;
115 /* Generate the filename and make sure that there isn't one called
116 it already. */
118 while (1)
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)
126 if (ptr->_errno == ENOSYS)
128 result[0] = '\0';
129 return 0;
131 break;
133 _close_r (ptr, t);
135 return 1;
138 char *
139 _DEFUN (_tmpnam_r, (p, s),
140 struct _reent *p _AND
141 char *s)
143 char *result;
144 int pid;
146 if (s == NULL)
148 /* ANSI states we must use an internal static buffer if s is NULL */
149 _REENT_CHECK_EMERGENCY(p);
150 result = _REENT_EMERGENCY(p);
152 else
154 result = s;
156 pid = _getpid_r (p);
158 if (worker (p, result, P_tmpdir, "t", pid, &p->_inc))
160 p->_inc++;
161 return result;
164 return NULL;
167 char *
168 _DEFUN (_tempnam_r, (p, dir, pfx),
169 struct _reent *p _AND
170 _CONST char *dir _AND
171 _CONST char *pfx)
173 char *filename;
174 int length;
175 _CONST char *prefix = (pfx) ? pfx : "";
176 if (dir == NULL && (dir = getenv ("TMPDIR")) == NULL)
177 dir = P_tmpdir;
179 /* two 8 digit numbers + . / */
180 length = strlen (dir) + strlen (prefix) + (4 * sizeof (int)) + 2 + 1;
182 filename = _malloc_r (p, length);
183 if (filename)
185 if (! worker (p, filename, dir, prefix,
186 _getpid_r (p) ^ (int) (_POINTER_INT) p, &p->_inc))
187 return NULL;
189 return filename;
192 #ifndef _REENT_ONLY
194 char *
195 _DEFUN (tempnam, (dir, pfx),
196 _CONST char *dir _AND
197 _CONST char *pfx)
199 return _tempnam_r (_REENT, dir, pfx);
202 char *
203 _DEFUN (tmpnam, (s),
204 char *s)
206 return _tmpnam_r (_REENT, s);
209 #endif