ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/paths.c
Revision: 2.4
Committed: Tue Jul 1 21:21:40 2003 UTC (20 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 2.3: +2 -2 lines
Log Message:
Compile fixes for gcc 3.3

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: paths.c,v 2.3 2003/06/30 14:59:11 schorsch Exp $";
3 #endif
4 /*
5 * Find a writeable tempfile directory.
6 * Create unique filenames therein, and possibly open the file.
7 *
8 */
9
10 #include "copyright.h"
11
12 #include "paths.h"
13
14
15 #define TEMPFILE_TEMPLATE "rtXXXXXX"
16 static const char *defaultpaths[] = DEFAULT_TEMPDIRS;
17
18
19 /* Return a writeable directory for temporary files */
20 /* If s is NULL, we return a static string */
21 char *
22 temp_directory(char *s, size_t len)
23 {
24 static char td[PATH_MAX]; /* remember */
25 char * ts = NULL;
26 int i = 0;
27
28 if (td[0] != '\0') { /* we already have one */
29 if (s == NULL) { return td; }
30 strncpy(s, td, len);
31 s[len-1] = '\0';
32 return s;
33 }
34 /* check where TMP and TEMP point to */
35 ts = getenv("TMP");
36 if (ts != NULL && access(ts, W_OK) == 0) {
37 strncpy(td, ts, sizeof(td));
38 td[sizeof(td)-1] = '\0';
39 }
40 if (ts == NULL) {
41 ts = getenv("TEMP");
42 if (ts != NULL && access(ts, W_OK) == 0) {
43 strncpy(td, ts, sizeof(td));
44 td[sizeof(td)-1] = '\0';
45 }
46 }
47 /* check the platform specific default paths in order */
48 while (ts == NULL) {
49 if (defaultpaths[i] == NULL) {
50 break;
51 }
52 if (access(defaultpaths[i], W_OK) == 0) {
53 ts = strncpy(td, defaultpaths[i], sizeof(td));
54 td[sizeof(td)-1] = '\0';
55 break;
56 }
57 i++;
58 }
59 /* we found something */
60 if (ts != NULL) {
61 if (s == NULL) { return td; }
62 strncpy(s, ts, len);
63 s[len-1] = '\0';
64 return s;
65 }
66 return NULL;
67 }
68
69
70 /* Concatenate two strings, leaving exactly one DIRSEP in between */
71 char *
72 append_filepath(char *s1, char *s2, size_t len)
73 {
74 size_t siz;
75 char *s;
76
77 siz = strlen(s1);
78 if (siz > 0) {
79 /* XXX siz > len is an error */
80 while (siz > 1 && ISDIRSEP(s1[siz-1])) {
81 s1[siz-1] = '\0';
82 siz--;
83 }
84 if (siz+1 <= len) {
85 s1[siz] = DIRSEP;
86 siz++;
87 }
88 } else if (len >= 2) { /* first path empty */
89 s1[0] = CURDIR;
90 s1[1] = DIRSEP;
91 siz = 2;
92 } else {
93 return NULL;
94 }
95 while (ISDIRSEP(s2[0])) {
96 s2++;
97 }
98 s = strncat(s1, s2, len-siz);
99 return s;
100 }
101
102
103 /* Do the actual work for tempfiles, except for the uniquification */
104 static char *
105 prepare_tmpname(char *s, size_t len, char *templ)
106 {
107 static char lp[PATH_MAX] = "\0";
108 char *ts = NULL;
109
110 if (s == NULL) { /* return our static string */
111 s = lp;
112 len = sizeof(lp);
113 }
114
115 ts = temp_directory(s, len);
116 if (ts == NULL) { return NULL; }
117 ts = append_filepath(ts, templ != NULL ? templ : TEMPFILE_TEMPLATE, len);
118 return ts;
119 }
120
121
122 /* Compose a *currently* unique name within a temporary directory */
123 /* If s is NULL, we return a static string */
124 /* If templ is NULL, we take our default template */
125 /* WARNING: On Windows, there's a maximum of 27 unique names within
126 one process for the same template. */
127 char *
128 temp_filename(char *s, size_t len, char *templ)
129 {
130 char *ts = NULL;
131
132 ts = prepare_tmpname(s, len, templ);
133 if (ts == NULL) { return NULL; }
134 return mktemp(ts);
135 }
136
137
138 /* Open a unique temp file in a safe way (not safe on Windows) */
139 /* If s is NULL, we use a static string the caller won't learn about */
140 /* If templ is NULL, we take our default template */
141 /* This one is supposed to protect against race conditions on unix */
142 /* WARNING: On Windows, there's no protection against race conditions */
143 /* WARNING: On Windows, there's a maximum of 27 unique names within
144 one process for the same template. */
145 int
146 temp_fd(char *s, size_t len, char *templ)
147 {
148 char *ts = NULL;
149
150 ts = prepare_tmpname(s, len, templ);
151 if (ts == NULL) return -1;
152 #ifdef _WIN32
153 ts = mktemp(ts);
154 if (ts == NULL) return -1;
155 return open(ts, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
156 #else
157 return mkstemp(ts);
158 #endif
159 }
160
161 /* As above, but returns a file pointer instead of a descriptor */
162 FILE *
163 temp_fp(char *s, size_t len, char *templ)
164 {
165 int fd = temp_fd(s, len, templ);
166 if (fd < 0) return NULL;
167 return fdopen(fd, "w+");
168 }
169
170
171 #ifdef TEST_MODULE
172 int main()
173 {
174 static char p[PATH_MAX] = "\0";
175 char * pp, *qq = NULL;
176 pp = temp_directory(p, sizeof(p));
177 printf("%s\n", pp);
178
179 qq = temp_filename(pp, sizeof(p), "//something/else_XXXXXX");
180 printf("%s\n", qq);
181
182 qq = temp_filename(pp, sizeof(p), NULL);
183 printf("%s\n", qq);
184 }
185 #endif
186