Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/tempname.c @ 17605:23cb5b2fd95b
relocatable-perl: like relocatable-script, but for Perl scripts
* build-aux/relocatable.pl.in: Add.
* doc/relocatable-maint.texi: Add documentation.
* modules/relocatable-perl: Add.
author | Reuben Thomas <rrt@sc3d.org> |
---|---|
date | Thu, 09 Jan 2014 22:31:42 +0000 |
parents | 344018b6e5d7 |
children | ab58d4870664 |
rev | line source |
---|---|
4020 | 1 /* tempname.c - generate the name of a temporary file. |
3192 | 2 |
17587 | 3 Copyright (C) 1991-2003, 2005-2007, 2009-2014 Free Software Foundation, Inc. |
3192 | 4 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7897
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
4020 | 6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7897
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7897
diff
changeset
|
8 (at your option) any later version. |
3192 | 9 |
4020 | 10 This program is distributed in the hope that it will be useful, |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7897
diff
changeset
|
15 You should have received a copy of the GNU General Public License |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7897
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
3192 | 17 |
7575
483757159eb6
* MODULES.html.sh: Document tempname.
Eric Blake <ebb9@byu.net>
parents:
7337
diff
changeset
|
18 /* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c. */ |
483757159eb6
* MODULES.html.sh: Document tempname.
Eric Blake <ebb9@byu.net>
parents:
7337
diff
changeset
|
19 |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
7162
diff
changeset
|
20 #if !_LIBC |
3192 | 21 # include <config.h> |
7575
483757159eb6
* MODULES.html.sh: Document tempname.
Eric Blake <ebb9@byu.net>
parents:
7337
diff
changeset
|
22 # include "tempname.h" |
3192 | 23 #endif |
24 | |
25 #include <sys/types.h> | |
26 #include <assert.h> | |
27 | |
28 #include <errno.h> | |
29 #ifndef __set_errno | |
30 # define __set_errno(Val) errno = (Val) | |
31 #endif | |
32 | |
33 #include <stdio.h> | |
34 #ifndef P_tmpdir | |
35 # define P_tmpdir "/tmp" | |
36 #endif | |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
37 #ifndef TMP_MAX |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
38 # define TMP_MAX 238328 |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
39 #endif |
3192 | 40 #ifndef __GT_FILE |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
41 # define __GT_FILE 0 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
42 # define __GT_DIR 1 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
43 # define __GT_NOCREATE 2 |
12233 | 44 #endif |
45 #if !_LIBC && (GT_FILE != __GT_FILE || GT_DIR != __GT_DIR \ | |
46 || GT_NOCREATE != __GT_NOCREATE) | |
47 # error report this to bug-gnulib@gnu.org | |
3192 | 48 #endif |
49 | |
4333 | 50 #include <stddef.h> |
3654
60143dd95a31
Include stdlib.h unconditionally. On some old systems for which
Jim Meyering <jim@meyering.net>
parents:
3653
diff
changeset
|
51 #include <stdlib.h> |
4691 | 52 #include <string.h> |
3654
60143dd95a31
Include stdlib.h unconditionally. On some old systems for which
Jim Meyering <jim@meyering.net>
parents:
3653
diff
changeset
|
53 |
5955
ace6ea191424
Assume HAVE_FCNTL_H (i.e., include <fcntl.h> unconditionally,
Jim Meyering <jim@meyering.net>
parents:
5907
diff
changeset
|
54 #include <fcntl.h> |
7897
b7a83a69ac23
* MODULES.html.sh (Support for systems lacking POSIX:2001): New
Paul Eggert <eggert@cs.ucla.edu>
parents:
7630
diff
changeset
|
55 #include <sys/time.h> |
7162
19c2e5121b2f
Add and change modules to make it easier for coreutils to use
Paul Eggert <eggert@cs.ucla.edu>
parents:
6806
diff
changeset
|
56 #include <stdint.h> |
6275 | 57 #include <unistd.h> |
3192 | 58 |
59 #include <sys/stat.h> | |
60 | |
61 #if _LIBC | |
62 # define struct_stat64 struct stat64 | |
63 #else | |
64 # define struct_stat64 struct stat | |
7575
483757159eb6
* MODULES.html.sh: Document tempname.
Eric Blake <ebb9@byu.net>
parents:
7337
diff
changeset
|
65 # define __gen_tempname gen_tempname |
3192 | 66 # define __getpid getpid |
67 # define __gettimeofday gettimeofday | |
68 # define __mkdir mkdir | |
12233 | 69 # define __open open |
5907 | 70 # define __lxstat64(version, file, buf) lstat (file, buf) |
17317
e67939626bf8
tempname: use secure_getenv
Paul Eggert <eggert@cs.ucla.edu>
parents:
17249
diff
changeset
|
71 # define __secure_getenv secure_getenv |
3192 | 72 #endif |
73 | |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
74 #ifdef _LIBC |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
75 # include <hp-timing.h> |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
76 # if HP_TIMING_AVAIL |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
77 # define RANDOM_BITS(Var) \ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
78 if (__builtin_expect (value == UINT64_C (0), 0)) \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
79 { \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
80 /* If this is the first time this function is used initialize \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
81 the variable we accumulate the value in to some somewhat \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
82 random value. If we'd not do this programs at startup time \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
83 might have a reduced set of possible names, at least on slow \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
84 machines. */ \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
85 struct timeval tv; \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
86 __gettimeofday (&tv, NULL); \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
87 value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
88 } \ |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
89 HP_TIMING_NOW (Var) |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
90 # endif |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
91 #endif |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
92 |
3212
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
93 /* Use the widest available unsigned type if uint64_t is not |
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
94 available. The algorithm below extracts a number less than 62**6 |
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
95 (approximately 2**35.725) from uint64_t, so ancient hosts where |
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
96 uintmax_t is only 32 bits lose about 3.725 bits of randomness, |
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
97 which is better than not having mkstemp at all. */ |
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
98 #if !defined UINT64_MAX && !defined uint64_t |
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
99 # define uint64_t uintmax_t |
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
100 #endif |
c211485f2a93
(uint64_t): Define to uintmax_t if
Jim Meyering <jim@meyering.net>
parents:
3192
diff
changeset
|
101 |
7575
483757159eb6
* MODULES.html.sh: Document tempname.
Eric Blake <ebb9@byu.net>
parents:
7337
diff
changeset
|
102 #if _LIBC |
3192 | 103 /* Return nonzero if DIR is an existent directory. */ |
104 static int | |
105 direxists (const char *dir) | |
106 { | |
107 struct_stat64 buf; | |
108 return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); | |
109 } | |
110 | |
111 /* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is | |
112 non-null and exists, uses it; otherwise uses the first of $TMPDIR, | |
113 P_tmpdir, /tmp that exists. Copies into TMPL a template suitable | |
114 for use with mk[s]temp. Will fail (-1) if DIR is non-null and | |
115 doesn't exist, none of the searched dirs exists, or there's not | |
116 enough space in TMPL. */ | |
117 int | |
118 __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
119 int try_tmpdir) |
3192 | 120 { |
121 const char *d; | |
122 size_t dlen, plen; | |
123 | |
124 if (!pfx || !pfx[0]) | |
125 { | |
126 pfx = "file"; | |
127 plen = 4; | |
128 } | |
129 else | |
130 { | |
131 plen = strlen (pfx); | |
132 if (plen > 5) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
133 plen = 5; |
3192 | 134 } |
135 | |
136 if (try_tmpdir) | |
137 { | |
138 d = __secure_getenv ("TMPDIR"); | |
139 if (d != NULL && direxists (d)) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
140 dir = d; |
3192 | 141 else if (dir != NULL && direxists (dir)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
142 /* nothing */ ; |
3192 | 143 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
144 dir = NULL; |
3192 | 145 } |
146 if (dir == NULL) | |
147 { | |
148 if (direxists (P_tmpdir)) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
149 dir = P_tmpdir; |
3192 | 150 else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp")) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
151 dir = "/tmp"; |
3192 | 152 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
153 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
154 __set_errno (ENOENT); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
155 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
156 } |
3192 | 157 } |
158 | |
159 dlen = strlen (dir); | |
160 while (dlen > 1 && dir[dlen - 1] == '/') | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
161 dlen--; /* remove trailing slashes */ |
3192 | 162 |
163 /* check we have room for "${dir}/${pfx}XXXXXX\0" */ | |
164 if (tmpl_len < dlen + 1 + plen + 6 + 1) | |
165 { | |
166 __set_errno (EINVAL); | |
167 return -1; | |
168 } | |
169 | |
170 sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx); | |
171 return 0; | |
172 } | |
7575
483757159eb6
* MODULES.html.sh: Document tempname.
Eric Blake <ebb9@byu.net>
parents:
7337
diff
changeset
|
173 #endif /* _LIBC */ |
3192 | 174 |
5907 | 175 /* These are the characters used in temporary file names. */ |
3192 | 176 static const char letters[] = |
177 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
178 | |
179 /* Generate a temporary file name based on TMPL. TMPL must match the | |
12233 | 180 rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). |
181 The name constructed does not exist at the time of the call to | |
182 __gen_tempname. TMPL is overwritten with the result. | |
3192 | 183 |
184 KIND may be one of: | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
185 __GT_NOCREATE: simply verify that the name does not exist |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
186 at the time of the call. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
187 __GT_FILE: create the file using open(O_CREAT|O_EXCL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
188 and return a read-write fd. The file is mode 0600. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
189 __GT_DIR: create a directory, which will be mode 0700. |
3192 | 190 |
191 We use a clever algorithm to get hard-to-predict names. */ | |
192 int | |
12233 | 193 __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) |
3192 | 194 { |
195 int len; | |
196 char *XXXXXX; | |
197 static uint64_t value; | |
198 uint64_t random_time_bits; | |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
199 unsigned int count; |
3635
2fb7a999ebce
(TMP_MAX): Remove; no longer needed.
Jim Meyering <jim@meyering.net>
parents:
3625
diff
changeset
|
200 int fd = -1; |
3192 | 201 int save_errno = errno; |
202 struct_stat64 st; | |
203 | |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
204 /* A lower bound on the number of temporary files to attempt to |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
205 generate. The maximum total number of temporary file names that |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
206 can exist for a given template is 62**6. It should never be |
16899
2311514e2d84
maint.mk: prohibit common grammar error: "all these"
Jim Meyering <meyering@redhat.com>
parents:
16201
diff
changeset
|
207 necessary to try all of these combinations. Instead if a reasonable |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
208 number of names is tried (we define reasonable as 62**3) fail to |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
209 give the system administrator the chance to remove the problems. */ |
7337
1735329d8bfd
* tempname.c (__gen_tempname): Change attempts_min
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
210 #define ATTEMPTS_MIN (62 * 62 * 62) |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
211 |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
212 /* The number of times to attempt to generate a temporary file. To |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
213 conform to POSIX, this must be no smaller than TMP_MAX. */ |
7337
1735329d8bfd
* tempname.c (__gen_tempname): Change attempts_min
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
214 #if ATTEMPTS_MIN < TMP_MAX |
1735329d8bfd
* tempname.c (__gen_tempname): Change attempts_min
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
215 unsigned int attempts = TMP_MAX; |
1735329d8bfd
* tempname.c (__gen_tempname): Change attempts_min
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
216 #else |
1735329d8bfd
* tempname.c (__gen_tempname): Change attempts_min
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
217 unsigned int attempts = ATTEMPTS_MIN; |
1735329d8bfd
* tempname.c (__gen_tempname): Change attempts_min
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
218 #endif |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
219 |
3192 | 220 len = strlen (tmpl); |
12233 | 221 if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) |
3192 | 222 { |
223 __set_errno (EINVAL); | |
224 return -1; | |
225 } | |
226 | |
227 /* This is where the Xs start. */ | |
12233 | 228 XXXXXX = &tmpl[len - 6 - suffixlen]; |
3192 | 229 |
230 /* Get some more or less random data. */ | |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
231 #ifdef RANDOM_BITS |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
232 RANDOM_BITS (random_time_bits); |
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
233 #else |
3192 | 234 { |
235 struct timeval tv; | |
236 __gettimeofday (&tv, NULL); | |
237 random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; | |
238 } | |
239 #endif | |
240 value += random_time_bits ^ __getpid (); | |
241 | |
3653
574daaf59139
Merge with version from libc.
Jim Meyering <jim@meyering.net>
parents:
3635
diff
changeset
|
242 for (count = 0; count < attempts; value += 7777, ++count) |
3192 | 243 { |
244 uint64_t v = value; | |
245 | |
246 /* Fill in the random bits. */ | |
247 XXXXXX[0] = letters[v % 62]; | |
248 v /= 62; | |
249 XXXXXX[1] = letters[v % 62]; | |
250 v /= 62; | |
251 XXXXXX[2] = letters[v % 62]; | |
252 v /= 62; | |
253 XXXXXX[3] = letters[v % 62]; | |
254 v /= 62; | |
255 XXXXXX[4] = letters[v % 62]; | |
256 v /= 62; | |
257 XXXXXX[5] = letters[v % 62]; | |
258 | |
259 switch (kind) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
260 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
261 case __GT_FILE: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
262 fd = __open (tmpl, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
263 (flags & ~O_ACCMODE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
264 | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
265 break; |
3192 | 266 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
267 case __GT_DIR: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
268 fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
269 break; |
3192 | 270 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
271 case __GT_NOCREATE: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
272 /* This case is backward from the other three. __gen_tempname |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
273 succeeds if __xstat fails because the name does not exist. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
274 Note the continue to bypass the common logic at the bottom |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
275 of the loop. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
276 if (__lxstat64 (_STAT_VER, tmpl, &st) < 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
277 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
278 if (errno == ENOENT) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
279 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
280 __set_errno (save_errno); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
281 return 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
282 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
283 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
284 /* Give up now. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
285 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
286 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
287 continue; |
3192 | 288 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
289 default: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
290 assert (! "invalid KIND in __gen_tempname"); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
291 abort (); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
292 } |
3192 | 293 |
294 if (fd >= 0) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
295 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
296 __set_errno (save_errno); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
297 return fd; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
298 } |
3192 | 299 else if (errno != EEXIST) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12233
diff
changeset
|
300 return -1; |
3192 | 301 } |
302 | |
303 /* We got out of the loop because we ran out of combinations to try. */ | |
304 __set_errno (EEXIST); | |
305 return -1; | |
306 } |