ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/paths.c
Revision: 2.3
Committed: Mon Jun 30 14:59:11 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.2: +13 -4 lines
Log Message:
Replaced most outdated BSD function calls with their posix equivalents, and cleaned up a few other platform dependencies.

File Contents

# User Rev Content
1 schorsch 2.1 #ifndef lint
2 schorsch 2.3 static const char RCSid[] = "$Id: paths.c,v 2.2 2003/06/26 00:58:09 schorsch Exp $";
3 schorsch 2.1 #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 schorsch 2.2 static char td[PATH_MAX]; /* remember */
25 schorsch 2.1 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 schorsch 2.2 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 schorsch 2.1 }
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 schorsch 2.3 static char lp[PATH_MAX] = "\0";
108 schorsch 2.1 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 schorsch 2.3 temp_fd(char *s, size_t len, char *templ)
147 schorsch 2.1 {
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 schorsch 2.3 return open(ts, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
156 schorsch 2.1 #else
157     return mkstemp(ts);
158     #endif
159 schorsch 2.3 }
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_file(s, len, templ);
166     if (fd < 0) return NULL;
167     return fdopen(fd, "w+");
168 schorsch 2.1 }
169    
170    
171 schorsch 2.2 #ifdef TEST_MODULE
172 schorsch 2.1 int main()
173     {
174     static char p[PATH_MAX] = "\0";
175     char * pp, *qq = NULL;
176     pp = temp_directory(p, sizeof(p));
177 schorsch 2.2 printf("%s\n", pp);
178 schorsch 2.1
179     qq = temp_filename(pp, sizeof(p), "//something/else_XXXXXX");
180     printf("%s\n", qq);
181 schorsch 2.2
182 schorsch 2.1 qq = temp_filename(pp, sizeof(p), NULL);
183     printf("%s\n", qq);
184     }
185     #endif
186