fixed more binutils issues (newer gcc/libc)
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / stdio / mktemp.c
blobf5757f3c7462b822887d1a716c189a7f945b199b
1 /* This is file MKTEMP.C */
2 /* This file may have been modified by DJ Delorie (Jan 1991). If so,
3 ** these modifications are Copyright (C) 1991 DJ Delorie.
4 */
6 /*
7 * Copyright (c) 1987 Regents of the University of California.
8 * All rights reserved.
10 * Redistribution and use in source and binary forms are permitted
11 * provided that: (1) source distributions retain this entire copyright
12 * notice and comment, and (2) distributions including binaries display
13 * the following acknowledgement: ``This product includes software
14 * developed by the University of California, Berkeley and its contributors''
15 * in the documentation or other materials provided with the distribution
16 * and in all advertising materials mentioning features or use of this
17 * software. Neither the name of the University nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 FUNCTION
27 <<mktemp>>, <<mkstemp>>---generate unused file name
29 INDEX
30 mktemp
31 INDEX
32 mkstemp
33 INDEX
34 _mktemp_r
35 INDEX
36 _mkstemp_r
38 ANSI_SYNOPSIS
39 #include <stdio.h>
40 char *mktemp(char *<[path]>);
41 int mkstemp(char *<[path]>);
43 char *_mktemp_r(void *<[reent]>, char *<[path]>);
44 int *_mkstemp_r(void *<[reent]>, char *<[path]>);
46 TRAD_SYNOPSIS
47 #include <stdio.h>
48 char *mktemp(<[path]>)
49 char *<[path]>;
51 int mkstemp(<[path]>)
52 char *<[path]>;
54 char *_mktemp_r(<[reent]>, <[path]>)
55 char *<[reent]>;
56 char *<[path]>;
58 int _mkstemp_r(<[reent]>, <[path]>)
59 char *<[reent]>;
60 char *<[path]>;
62 DESCRIPTION
63 <<mktemp>> and <<mkstemp>> attempt to generate a file name that is not
64 yet in use for any existing file. <<mkstemp>> creates the file and
65 opens it for reading and writing; <<mktemp>> simply generates the file name.
67 You supply a simple pattern for the generated file name, as the string
68 at <[path]>. The pattern should be a valid filename (including path
69 information if you wish) ending with some number of `<<X>>'
70 characters. The generated filename will match the leading part of the
71 name you supply, with the trailing `<<X>>' characters replaced by some
72 combination of digits and letters.
74 The alternate functions <<_mktemp_r>> and <<_mkstemp_r>> are reentrant
75 versions. The extra argument <[reent]> is a pointer to a reentrancy
76 structure.
78 RETURNS
79 <<mktemp>> returns the pointer <[path]> to the modified string
80 representing an unused filename, unless it could not generate one, or
81 the pattern you provided is not suitable for a filename; in that case,
82 it returns <<NULL>>.
84 <<mkstemp>> returns a file descriptor to the newly created file,
85 unless it could not generate an unused filename, or the pattern you
86 provided is not suitable for a filename; in that case, it returns
87 <<-1>>.
89 PORTABILITY
90 ANSI C does not require either <<mktemp>> or <<mkstemp>>; the System
91 V Interface Definition requires <<mktemp>> as of Issue 2.
93 Supporting OS subroutines required: <<getpid>>, <<open>>, <<stat>>.
96 #include <sys/types.h>
97 #include <fcntl.h>
98 #include <sys/stat.h>
99 #include <errno.h>
100 #include <stdio.h>
101 #include <ctype.h>
102 #include <reent.h>
104 static int
105 _DEFUN (_gettemp, (ptr, path, doopen),
106 struct _reent *ptr _AND
107 char *path _AND
108 register int *doopen)
110 register char *start, *trv;
111 struct stat sbuf;
112 unsigned int pid;
114 pid = _getpid_r (ptr);
115 for (trv = path; *trv; ++trv) /* extra X's get set to 0's */
116 continue;
117 while (*--trv == 'X')
119 *trv = (pid % 10) + '0';
120 pid /= 10;
124 * Check the target directory; if you have six X's and it
125 * doesn't exist this runs for a *very* long time.
128 for (start = trv + 1;; --trv)
130 if (trv <= path)
131 break;
132 if (*trv == '/')
134 *trv = '\0';
135 #ifdef __USE_INTERNAL_STAT64
136 if (_stat64_r (ptr, path, &sbuf))
137 #else
138 if (_stat_r (ptr, path, &sbuf))
139 #endif
140 return (0);
141 if (!(sbuf.st_mode & S_IFDIR))
143 ptr->_errno = ENOTDIR;
144 return (0);
146 *trv = '/';
147 break;
151 for (;;)
153 if (doopen)
155 if ((*doopen = _open_r (ptr, path, O_CREAT | O_EXCL | O_RDWR, 0600))
156 >= 0)
157 return 1;
158 #if defined(__CYGWIN__)
159 if (ptr->_errno != EEXIST && ptr->_errno != EACCES)
160 #else
161 if (ptr->_errno != EEXIST)
162 #endif
163 return 0;
165 #ifdef __USE_INTERNAL_STAT64
166 else if (_stat64_r (ptr, path, &sbuf))
167 #else
168 else if (_stat_r (ptr, path, &sbuf))
169 #endif
170 return (ptr->_errno == ENOENT ? 1 : 0);
172 /* tricky little algorithm for backward compatibility */
173 for (trv = start;;)
175 if (!*trv)
176 return 0;
177 if (*trv == 'z')
178 *trv++ = 'a';
179 else
181 if (isdigit (*trv))
182 *trv = 'a';
183 else
184 ++ * trv;
185 break;
189 /*NOTREACHED*/
193 _DEFUN (_mkstemp_r, (ptr, path),
194 struct _reent *ptr _AND
195 char *path)
197 int fd;
199 return (_gettemp (ptr, path, &fd) ? fd : -1);
202 char *
203 _DEFUN (_mktemp_r, (ptr, path),
204 struct _reent *ptr _AND
205 char *path)
207 return (_gettemp (ptr, path, (int *) NULL) ? path : (char *) NULL);
210 #ifndef _REENT_ONLY
213 _DEFUN (mkstemp, (path),
214 char *path)
216 int fd;
218 return (_gettemp (_REENT, path, &fd) ? fd : -1);
221 char *
222 _DEFUN (mktemp, (path),
223 char *path)
225 return (_gettemp (_REENT, path, (int *) NULL) ? path : (char *) NULL);
228 #endif /* ! defined (_REENT_ONLY) */