Mercurial > hg > octave-nkf
annotate liboctave/tempname.c @ 10317:42d098307c30
untabify additional source files
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 11 Feb 2010 13:30:42 -0500 |
parents | 0522a65bcd56 |
children | 12df7854fa7c |
rev | line source |
---|---|
828 | 1 /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. |
2 This file is part of the GNU C Library. | |
3 | |
4 The GNU C Library is free software; you can redistribute it and/or | |
5 modify it under the terms of the GNU General Public License as | |
6 published by the Free Software Foundation; either version 2 of the | |
7 License, or (at your option) any later version. | |
8 | |
9 The GNU C Library is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public | |
15 License along with the GNU C Library; see the file COPYING. If | |
5307 | 16 not, write to the Free Software Foundation, Inc., 51 Franklin Street, |
17 Fifth Floor, Boston, MA 02110-1301, USA. */ | |
828 | 18 |
19 #ifdef HAVE_CONFIG_H | |
1243 | 20 #include <config.h> |
828 | 21 #endif |
22 | |
23 #ifndef HAVE_TEMPNAM | |
24 | |
25 #include <errno.h> | |
26 #include <stddef.h> | |
27 #include <stdio.h> | |
28 #include <stdlib.h> | |
29 #include <string.h> | |
1350 | 30 |
31 #include <sys/types.h> | |
32 #include <unistd.h> | |
33 | |
828 | 34 #include <fcntl.h> |
35 | |
1056 | 36 #include "statdefs.h" |
37 | |
828 | 38 #ifndef FILENAME_MAX |
39 #ifdef MAXPATHLEN | |
40 #define FILENAME_MAX MAXPATHLEN | |
41 #else | |
42 #define FILENAME_MAX 1024 | |
43 #endif | |
44 #endif | |
45 | |
46 #ifndef P_tmpdir | |
47 #define P_tmpdir "/usr/tmp/" | |
48 #endif | |
49 | |
50 /* Return nonzero if DIR is an existent directory. */ | |
51 static int | |
52 diraccess (const char *dir) | |
53 { | |
54 struct stat buf; | |
55 return stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode); | |
56 } | |
57 | |
58 /* Return nonzero if FILE exists. */ | |
59 static int | |
60 exists (const char *file) | |
61 { | |
62 /* We can stat the file even if we can't read its data. */ | |
63 struct stat st; | |
64 int save = errno; | |
65 if (stat (file, &st) == 0) | |
66 return 1; | |
67 else | |
68 { | |
69 /* We report that the file exists if stat failed for a reason other | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
70 than nonexistence. In this case, it may or may not exist, and we |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
71 don't know; but reporting that it does exist will never cause any |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
72 trouble, while reporting that it doesn't exist when it does would |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
73 violate the interface of __stdio_gen_tempname. */ |
828 | 74 int exists = errno != ENOENT; |
75 errno = save; | |
76 return exists; | |
77 } | |
78 } | |
79 | |
80 | |
81 /* These are the characters used in temporary filenames. */ | |
82 static const char letters[] = | |
83 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
84 | |
85 /* Generate a temporary filename and return it (in a static buffer). If | |
86 STREAMPTR is not NULL, open a stream "w+b" on the file and set | |
87 *STREAMPTR to it. If DIR_SEARCH is nonzero, DIR and PFX are used as | |
88 described for tempnam. If not, a temporary filename in P_tmpdir with no | |
89 special prefix is generated. If LENPTR is not NULL, *LENPTR is set the | |
90 to length (including the terminating '\0') of the resultant filename, | |
91 which is returned. This goes through a cyclic pattern of all possible | |
92 filenames consisting of five decimal digits of the current pid and three | |
93 of the characters in `letters'. Data for tempnam and tmpnam is kept | |
94 separate, but when tempnam is using P_tmpdir and no prefix (i.e, it is | |
95 identical to tmpnam), the same data is used. Each potential filename is | |
96 tested for an already-existing file of the same name, and no name of an | |
97 existing file will be returned. When the cycle reaches its end | |
98 (12345ZZZ), NULL is returned. */ | |
99 char * | |
100 __stdio_gen_tempname (const char *dir, const char *pfx, | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
101 int dir_search, size_t *lenptr, |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
102 FILE **streamptr) |
828 | 103 { |
104 int saverrno = errno; | |
105 static const char tmpdir[] = P_tmpdir; | |
106 static size_t indices[2]; | |
107 size_t *idx; | |
108 static char buf[FILENAME_MAX]; | |
109 static pid_t oldpid = (pid_t) 0; | |
110 pid_t pid = getpid(); | |
111 register size_t len, plen, dlen; | |
112 | |
113 if (dir_search) | |
114 { | |
115 register const char *d = getenv("TMPDIR"); | |
116 if (d != NULL && !diraccess(d)) | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
117 d = NULL; |
828 | 118 if (d == NULL && dir != NULL && diraccess(dir)) |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
119 d = dir; |
828 | 120 if (d == NULL && diraccess(tmpdir)) |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
121 d = tmpdir; |
828 | 122 if (d == NULL && diraccess("/tmp")) |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
123 d = "/tmp"; |
828 | 124 if (d == NULL) |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
125 { |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
126 errno = ENOENT; |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
127 return NULL; |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
128 } |
828 | 129 dir = d; |
130 } | |
131 else | |
132 dir = tmpdir; | |
133 | |
134 dlen = strlen (dir); | |
135 | |
136 /* Remove trailing slashes from the directory name. */ | |
137 while (dlen > 1 && dir[dlen - 1] == '/') | |
138 --dlen; | |
139 | |
140 if (pfx != NULL && *pfx != '\0') | |
141 { | |
142 plen = strlen(pfx); | |
143 if (plen > 5) | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
144 plen = 5; |
828 | 145 } |
146 else | |
147 plen = 0; | |
148 | |
149 if (dir != tmpdir && !strcmp(dir, tmpdir)) | |
150 dir = tmpdir; | |
151 idx = &indices[(plen == 0 && dir == tmpdir) ? 1 : 0]; | |
152 | |
153 if (pid != oldpid) | |
154 { | |
155 oldpid = pid; | |
156 indices[0] = indices[1] = 0; | |
157 } | |
158 | |
159 len = dlen + 1 + plen + 5 + 3; | |
160 for (; *idx < ((sizeof (letters) - 1) * (sizeof (letters) - 1) * | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
161 (sizeof (letters) - 1)); |
828 | 162 ++*idx) |
163 { | |
164 /* Construct a file name and see if it already exists. | |
165 | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
166 We use a single counter in *IDX to cycle each of three |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
167 character positions through each of 62 possible letters. */ |
828 | 168 |
169 if (sizeof (buf) < len) | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
170 return NULL; |
828 | 171 |
172 sprintf (buf, "%.*s/%.*s%.5d%c%c%c", | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
173 (int) dlen, dir, (int) plen, |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
174 pfx, pid % 100000, |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
175 letters[*idx |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
176 % (sizeof (letters) - 1)], |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
177 letters[(*idx / (sizeof (letters) - 1)) |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
178 % (sizeof (letters) - 1)], |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
179 letters[(*idx / ((sizeof (letters) - 1) * |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
180 (sizeof (letters) - 1))) |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
181 % (sizeof (letters) - 1)] |
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
182 ); |
828 | 183 |
184 if (! buf || strlen (buf) != (int) len) | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
185 return NULL; |
828 | 186 |
187 if (streamptr != NULL) | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
188 abort (); |
828 | 189 else if (exists (buf)) |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
190 continue; |
828 | 191 |
192 /* If the file already existed we have continued the loop above, | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
193 so we only get here when we have a winning name to return. */ |
828 | 194 |
195 errno = saverrno; | |
196 | |
197 if (lenptr != NULL) | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
198 *lenptr = len + 1; |
828 | 199 return buf; |
200 } | |
201 | |
202 /* We got out of the loop because we ran out of combinations to try. */ | |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
203 errno = EEXIST; /* ? */ |
828 | 204 return NULL; |
205 } | |
206 | |
207 #endif |