1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include "apr_private.h"
17 #include "apr_file_io.h"
18 #include "apr_strings.h"
23 * Currently, this variable is a bit of misnomer.
24 * The intention is to have this in APR's global pool so that we don't have
25 * to go through this every time.
27 static char global_temp_dir[APR_PATH_MAX+1] = { 0 };
29 /* Try to open a temporary file in the temporary dir, write to it,
31 static int test_tempdir(const char *temp_dir, apr_pool_t *p)
33 apr_file_t *dummy_file;
34 const char *path = apr_pstrcat(p, temp_dir, "/apr-tmp.XXXXXX", NULL);
36 if (apr_file_mktemp(&dummy_file, (char *)path, 0, p) == APR_SUCCESS) {
37 if (apr_file_putc('!', dummy_file) == APR_SUCCESS) {
38 if (apr_file_close(dummy_file) == APR_SUCCESS) {
47 APR_DECLARE(apr_status_t) apr_temp_dir_get(const char **temp_dir,
51 const char *try_dirs[] = { "/tmp", "/usr/tmp", "/var/tmp" };
52 const char *try_envs[] = { "TMP", "TEMP", "TMPDIR" };
56 /* Our goal is to find a temporary directory suitable for writing
57 into. We'll only pay the price once if we're successful -- we
58 cache our successful find. Here's the order in which we'll try
64 "C:\TEMP" (windows only)
65 "SYS:\TMP" (netware only)
69 P_tmpdir (POSIX define)
72 NOTE: This algorithm is basically the same one used by Python
73 2.2's tempfile.py module. */
75 /* Try the environment first. */
76 for (i = 0; i < (sizeof(try_envs) / sizeof(const char *)); i++) {
78 apr_err = apr_env_get(&value, try_envs[i], p);
79 if ((apr_err == APR_SUCCESS) && value) {
80 apr_size_t len = strlen(value);
81 if (len && (len < APR_PATH_MAX) && test_tempdir(value, p)) {
82 memcpy(global_temp_dir, value, len + 1);
89 /* Next, on Win32, try the C:\TEMP directory. */
90 if (test_tempdir("C:\\TEMP", p)) {
91 memcpy(global_temp_dir, "C:\\TEMP", 7 + 1);
96 /* Next, on NetWare, try the SYS:/TMP directory. */
97 if (test_tempdir("SYS:/TMP", p)) {
98 memcpy(global_temp_dir, "SYS:/TMP", 8 + 1);
103 /* Next, try a set of hard-coded paths. */
104 for (i = 0; i < (sizeof(try_dirs) / sizeof(const char *)); i++) {
105 if (test_tempdir(try_dirs[i], p)) {
106 memcpy(global_temp_dir, try_dirs[i], strlen(try_dirs[i]) + 1);
113 * If we have it, use the POSIX definition of where
114 * the tmpdir should be
116 if (test_tempdir(P_tmpdir, p)) {
117 memcpy(global_temp_dir, P_tmpdir, strlen(P_tmpdir) +1);
122 /* Finally, try the current working directory. */
123 if (APR_SUCCESS == apr_filepath_get(&cwd, APR_FILEPATH_NATIVE, p)) {
124 if (test_tempdir(cwd, p)) {
125 memcpy(global_temp_dir, cwd, strlen(cwd) + 1);
131 if (global_temp_dir[0]) {
132 *temp_dir = apr_pstrdup(p, global_temp_dir);