ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/paths.c
Revision: 2.2
Committed: Thu Jun 26 00:58:09 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.1: +22 -13 lines
Log Message:
Abstracted process and path handling for Windows.
Renamed FLOAT to RREAL because of conflict on Windows.
Added conditional compiles for some signal handlers.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: paths.c,v 2.1 2003/06/08 12:01:52 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"; /* remember what we found last time */
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_file(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 fopen(ts, "r+b"); /* XXX des "b" need to be an option? */
156 #else
157 return mkstemp(ts);
158 #endif
159 }
160
161
162 #ifdef TEST_MODULE
163 int main()
164 {
165 static char p[PATH_MAX] = "\0";
166 char * pp, *qq = NULL;
167 pp = temp_directory(p, sizeof(p));
168 printf("%s\n", pp);
169
170 qq = temp_filename(pp, sizeof(p), "//something/else_XXXXXX");
171 printf("%s\n", qq);
172
173 qq = temp_filename(pp, sizeof(p), NULL);
174 printf("%s\n", qq);
175 }
176 #endif
177