Mercurial > hg > octave-kai > gnulib-hg
annotate lib/tmpdir.c @ 17449:960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
* lib/tmpdir.c (__libc_secure_getenv) [!_LIBC]: Rename from
__secure_getenv, so that we're more like the glibc version.
All uses changed.
(path_search): Don't put slash after directory if __VMS.
Problem reported by Steven M. Schweda in
<http://lists.gnu.org/archive/html/bug-gnulib/2013-07/msg00019.html>.
Do not remove trailing slash from "//".
Do not assume dlen <= INT_MAX.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Mon, 15 Jul 2013 09:44:19 -0700 |
parents | 087501e891d9 |
children | fcdfb5b7741a |
rev | line source |
---|---|
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16214
diff
changeset
|
1 /* Copyright (C) 1999, 2001-2002, 2006, 2009-2013 Free Software Foundation, |
12559
c2cbabec01dd
update nearly all FSF copyright year lists to include 2010
Jim Meyering <meyering@redhat.com>
parents:
12518
diff
changeset
|
2 Inc. |
7043 | 3 This file is part of the GNU C Library. |
4 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7588
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
7139
adb21c293305
Add copyright notices to long-enough files that lack them, since
Paul Eggert <eggert@cs.ucla.edu>
parents:
7043
diff
changeset
|
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:
7588
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:
7588
diff
changeset
|
8 (at your option) any later version. |
7043 | 9 |
7139
adb21c293305
Add copyright notices to long-enough files that lack them, since
Paul Eggert <eggert@cs.ucla.edu>
parents:
7043
diff
changeset
|
10 This program is distributed in the hope that it will be useful, |
7043 | 11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
7139
adb21c293305
Add copyright notices to long-enough files that lack them, since
Paul Eggert <eggert@cs.ucla.edu>
parents:
7043
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
adb21c293305
Add copyright notices to long-enough files that lack them, since
Paul Eggert <eggert@cs.ucla.edu>
parents:
7043
diff
changeset
|
13 GNU General Public License for more details. |
7043 | 14 |
7139
adb21c293305
Add copyright notices to long-enough files that lack them, since
Paul Eggert <eggert@cs.ucla.edu>
parents:
7043
diff
changeset
|
15 You should have received a copy of the GNU General Public License |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7588
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
7043 | 17 |
18 /* Extracted from sysdeps/posix/tempname.c. */ | |
19 | |
7304
1c4ed7637c24
Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
7139
diff
changeset
|
20 #include <config.h> |
7043 | 21 |
22 /* Specification. */ | |
23 #include "tmpdir.h" | |
24 | |
25 #include <stdbool.h> | |
26 #include <stdlib.h> | |
27 #include <string.h> | |
28 | |
29 #include <errno.h> | |
30 #ifndef __set_errno | |
31 # define __set_errno(Val) errno = (Val) | |
32 #endif | |
33 | |
34 #include <stdio.h> | |
35 #ifndef P_tmpdir | |
15534
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
36 # ifdef _P_tmpdir /* native Windows */ |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
37 # define P_tmpdir _P_tmpdir |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
38 # else |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
39 # define P_tmpdir "/tmp" |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
40 # endif |
7043 | 41 #endif |
42 | |
43 #include <sys/stat.h> | |
44 | |
15534
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
45 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
46 # define WIN32_LEAN_AND_MEAN /* avoid including junk */ |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
47 # include <windows.h> |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
48 #endif |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
49 |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
50 #include "pathmax.h" |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
51 |
7043 | 52 #if _LIBC |
53 # define struct_stat64 struct stat64 | |
54 #else | |
55 # define struct_stat64 struct stat | |
17449
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
56 # define __libc_secure_getenv secure_getenv |
7043 | 57 # define __xstat64(version, path, buf) stat (path, buf) |
58 #endif | |
59 | |
60 /* Pathname support. | |
61 ISSLASH(C) tests whether C is a directory separator character. | |
62 */ | |
63 #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ | |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
64 /* Native Windows, Cygwin, OS/2, DOS */ |
7043 | 65 # define ISSLASH(C) ((C) == '/' || (C) == '\\') |
66 #else | |
67 /* Unix */ | |
68 # define ISSLASH(C) ((C) == '/') | |
69 #endif | |
70 | |
71 | |
72 /* Return nonzero if DIR is an existent directory. */ | |
73 static bool | |
74 direxists (const char *dir) | |
75 { | |
76 struct_stat64 buf; | |
77 return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); | |
78 } | |
79 | |
80 /* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is | |
81 non-null and exists, uses it; otherwise uses the first of $TMPDIR, | |
82 P_tmpdir, /tmp that exists. Copies into TMPL a template suitable | |
83 for use with mk[s]temp. Will fail (-1) if DIR is non-null and | |
84 doesn't exist, none of the searched dirs exists, or there's not | |
85 enough space in TMPL. */ | |
86 int | |
87 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:
9309
diff
changeset
|
88 bool try_tmpdir) |
7043 | 89 { |
90 const char *d; | |
91 size_t dlen, plen; | |
17449
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
92 #ifdef __VMS |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
93 bool add_slash = false; |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
94 #else |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
95 bool add_slash = true; |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
96 #endif |
7043 | 97 |
98 if (!pfx || !pfx[0]) | |
99 { | |
100 pfx = "file"; | |
101 plen = 4; | |
102 } | |
103 else | |
104 { | |
105 plen = strlen (pfx); | |
106 if (plen > 5) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
107 plen = 5; |
7043 | 108 } |
109 | |
110 if (try_tmpdir) | |
111 { | |
17449
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
112 d = __libc_secure_getenv ("TMPDIR"); |
7043 | 113 if (d != NULL && direxists (d)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
114 dir = d; |
7043 | 115 else if (dir != NULL && direxists (dir)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
116 /* nothing */ ; |
7043 | 117 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
118 dir = NULL; |
7043 | 119 } |
120 if (dir == NULL) | |
121 { | |
15534
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
122 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
123 char dirbuf[PATH_MAX]; |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
124 DWORD retval; |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
125 |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
126 /* Find Windows temporary file directory. |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
127 We try this before P_tmpdir because Windows defines P_tmpdir to "\\" |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
128 and will therefore try to put all temporary files in the root |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
129 directory (unless $TMPDIR is set). */ |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
130 retval = GetTempPath (PATH_MAX, dirbuf); |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
131 if (retval > 0 && retval < PATH_MAX && direxists (dirbuf)) |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
132 dir = dirbuf; |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
133 else |
3ef509e539a1
tmpdir: Use a good default directory on native Windows.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
134 #endif |
7043 | 135 if (direxists (P_tmpdir)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
136 dir = P_tmpdir; |
7043 | 137 else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp")) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
138 dir = "/tmp"; |
7043 | 139 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
140 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
141 __set_errno (ENOENT); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
142 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
143 } |
7043 | 144 } |
145 | |
17449
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
146 /* Remove trailing slashes, except remove just one from "//". */ |
7043 | 147 dlen = strlen (dir); |
17449
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
148 if (dlen == 2 && ISSLASH (dir[0]) && ISSLASH (dir[1])) |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
149 dlen--; |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
150 else |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
151 while (0 < dlen && ISSLASH (dir[dlen - 1])) |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
152 dlen--; |
7043 | 153 |
154 /* check we have room for "${dir}/${pfx}XXXXXX\0" */ | |
17449
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
155 if (tmpl_len < dlen + add_slash + plen + 6 + 1) |
7043 | 156 { |
157 __set_errno (EINVAL); | |
158 return -1; | |
159 } | |
160 | |
17449
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
161 memcpy (tmpl, dir, dlen); |
960eeef4f5eb
tmpdir: port to VMS, to // != /, and to long dirs
Paul Eggert <eggert@cs.ucla.edu>
parents:
17318
diff
changeset
|
162 sprintf (tmpl + dlen, &"/%.*sXXXXXX"[!add_slash], pfx, (int) plen); |
7043 | 163 return 0; |
164 } |