unix,win: add uv_os_tmpdir()
PR-URL: https://github.com/libuv/libuv/pull/672 Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
d41749d546
commit
c0fa2e7518
@ -243,6 +243,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-timer-again.c \
|
test/test-timer-again.c \
|
||||||
test/test-timer-from-check.c \
|
test/test-timer-from-check.c \
|
||||||
test/test-timer.c \
|
test/test-timer.c \
|
||||||
|
test/test-tmpdir.c \
|
||||||
test/test-tty.c \
|
test/test-tty.c \
|
||||||
test/test-udp-bind.c \
|
test/test-udp-bind.c \
|
||||||
test/test-udp-create-socket-early.c \
|
test/test-udp-create-socket-early.c \
|
||||||
|
|||||||
@ -155,6 +155,7 @@ test/test-threadpool-cancel.c
|
|||||||
test/test-threadpool.c
|
test/test-threadpool.c
|
||||||
test/test-timer-again.c
|
test/test-timer-again.c
|
||||||
test/test-timer.c
|
test/test-timer.c
|
||||||
|
test/test-tmpdir.c
|
||||||
test/test-tty.c
|
test/test-tty.c
|
||||||
test/test-udp-dgram-too-big.c
|
test/test-udp-dgram-too-big.c
|
||||||
test/test-udp-ipv6.c
|
test/test-udp-ipv6.c
|
||||||
|
|||||||
@ -273,6 +273,22 @@ API
|
|||||||
|
|
||||||
.. versionadded:: 1.6.0
|
.. versionadded:: 1.6.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_os_tmpdir(char* buffer, size_t* size)
|
||||||
|
|
||||||
|
Gets the temp directory. On Windows, `uv_os_tmpdir()` uses `GetTempPathW()`.
|
||||||
|
On all other operating systems, `uv_os_tmpdir()` uses the first environment
|
||||||
|
variable found in the ordered list `TMPDIR`, `TMP`, `TEMP`, and `TEMPDIR`.
|
||||||
|
If none of these are found, the path `"/tmp"` is used, or, on Android,
|
||||||
|
`"/data/local/tmp"` is used. The temp directory is stored in `buffer`. When
|
||||||
|
`uv_os_tmpdir()` is called, `size` indicates the maximum size of `buffer`.
|
||||||
|
On success or `UV_ENOBUFS` failure, `size` is set to the string length of
|
||||||
|
`buffer` (which does not include the terminating null).
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
`uv_os_tmpdir()` is not thread safe.
|
||||||
|
|
||||||
|
.. versionadded:: 1.9.0
|
||||||
|
|
||||||
.. uint64_t uv_get_free_memory(void)
|
.. uint64_t uv_get_free_memory(void)
|
||||||
.. c:function:: uint64_t uv_get_total_memory(void)
|
.. c:function:: uint64_t uv_get_total_memory(void)
|
||||||
|
|
||||||
|
|||||||
@ -1049,6 +1049,7 @@ typedef struct {
|
|||||||
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
|
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
|
||||||
|
|
||||||
UV_EXTERN int uv_os_homedir(char* buffer, size_t* size);
|
UV_EXTERN int uv_os_homedir(char* buffer, size_t* size);
|
||||||
|
UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size);
|
||||||
|
|
||||||
UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
|
UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
|
||||||
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
|
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
|
||||||
|
|||||||
@ -1102,3 +1102,54 @@ int uv_os_homedir(char* buffer, size_t* size) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv_os_tmpdir(char* buffer, size_t* size) {
|
||||||
|
const char* buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (buffer == NULL || size == NULL || *size == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
#define CHECK_ENV_VAR(name) \
|
||||||
|
do { \
|
||||||
|
buf = getenv(name); \
|
||||||
|
if (buf != NULL) \
|
||||||
|
goto return_buffer; \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* Check the TMPDIR, TMP, TEMP, and TEMPDIR environment variables in order */
|
||||||
|
CHECK_ENV_VAR("TMPDIR");
|
||||||
|
CHECK_ENV_VAR("TMP");
|
||||||
|
CHECK_ENV_VAR("TEMP");
|
||||||
|
CHECK_ENV_VAR("TEMPDIR");
|
||||||
|
|
||||||
|
#undef CHECK_ENV_VAR
|
||||||
|
|
||||||
|
/* No temp environment variables defined */
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
buf = "/data/local/tmp";
|
||||||
|
#else
|
||||||
|
buf = "/tmp";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return_buffer:
|
||||||
|
len = strlen(buf);
|
||||||
|
|
||||||
|
if (len >= *size) {
|
||||||
|
*size = len;
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The returned directory should not have a trailing slash. */
|
||||||
|
if (len > 1 && buf[len - 1] == '/') {
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer, buf, len + 1);
|
||||||
|
buffer[len] = '\0';
|
||||||
|
*size = len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -1230,3 +1230,56 @@ convert_buffer:
|
|||||||
*size = bufsize - 1;
|
*size = bufsize - 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv_os_tmpdir(char* buffer, size_t* size) {
|
||||||
|
wchar_t path[MAX_PATH + 1];
|
||||||
|
DWORD bufsize;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (buffer == NULL || size == NULL || *size == 0)
|
||||||
|
return UV_EINVAL;
|
||||||
|
|
||||||
|
len = GetTempPathW(MAX_PATH + 1, path);
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
return uv_translate_sys_error(GetLastError());
|
||||||
|
} else if (len > MAX_PATH + 1) {
|
||||||
|
/* This should not be possible */
|
||||||
|
return UV_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The returned directory should not have a trailing slash, unless it */
|
||||||
|
/* points at a drive root, like c:\. Remove it if needed.*/
|
||||||
|
if (path[len - 1] == L'\\' &&
|
||||||
|
!(len == 3 && path[1] == L':')) {
|
||||||
|
len--;
|
||||||
|
path[len] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check how much space we need */
|
||||||
|
bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
|
||||||
|
|
||||||
|
if (bufsize == 0) {
|
||||||
|
return uv_translate_sys_error(GetLastError());
|
||||||
|
} else if (bufsize > *size) {
|
||||||
|
*size = bufsize - 1;
|
||||||
|
return UV_ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert to UTF-8 */
|
||||||
|
bufsize = WideCharToMultiByte(CP_UTF8,
|
||||||
|
0,
|
||||||
|
path,
|
||||||
|
-1,
|
||||||
|
buffer,
|
||||||
|
*size,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (bufsize == 0)
|
||||||
|
return uv_translate_sys_error(GetLastError());
|
||||||
|
|
||||||
|
*size = bufsize - 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -199,6 +199,7 @@ TEST_DECLARE (cwd_and_chdir)
|
|||||||
TEST_DECLARE (get_memory)
|
TEST_DECLARE (get_memory)
|
||||||
TEST_DECLARE (handle_fileno)
|
TEST_DECLARE (handle_fileno)
|
||||||
TEST_DECLARE (homedir)
|
TEST_DECLARE (homedir)
|
||||||
|
TEST_DECLARE (tmpdir)
|
||||||
TEST_DECLARE (hrtime)
|
TEST_DECLARE (hrtime)
|
||||||
TEST_DECLARE (getaddrinfo_fail)
|
TEST_DECLARE (getaddrinfo_fail)
|
||||||
TEST_DECLARE (getaddrinfo_fail_sync)
|
TEST_DECLARE (getaddrinfo_fail_sync)
|
||||||
@ -586,6 +587,8 @@ TASK_LIST_START
|
|||||||
|
|
||||||
TEST_ENTRY (homedir)
|
TEST_ENTRY (homedir)
|
||||||
|
|
||||||
|
TEST_ENTRY (tmpdir)
|
||||||
|
|
||||||
TEST_ENTRY (hrtime)
|
TEST_ENTRY (hrtime)
|
||||||
|
|
||||||
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
|
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
|
||||||
|
|||||||
50
test/test-tmpdir.c
Normal file
50
test/test-tmpdir.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include "uv.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define PATHMAX 1024
|
||||||
|
#define SMALLPATH 1
|
||||||
|
|
||||||
|
TEST_IMPL(tmpdir) {
|
||||||
|
char tmpdir[PATHMAX];
|
||||||
|
size_t len;
|
||||||
|
char last;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Test the normal case */
|
||||||
|
len = sizeof tmpdir;
|
||||||
|
tmpdir[0] = '\0';
|
||||||
|
|
||||||
|
ASSERT(strlen(tmpdir) == 0);
|
||||||
|
r = uv_os_tmpdir(tmpdir, &len);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
ASSERT(strlen(tmpdir) == len);
|
||||||
|
ASSERT(len > 0);
|
||||||
|
ASSERT(tmpdir[len] == '\0');
|
||||||
|
|
||||||
|
if (len > 1) {
|
||||||
|
last = tmpdir[len - 1];
|
||||||
|
#ifdef _WIN32
|
||||||
|
ASSERT(last != '\\');
|
||||||
|
#else
|
||||||
|
ASSERT(last != '/');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test the case where the buffer is too small */
|
||||||
|
len = SMALLPATH;
|
||||||
|
r = uv_os_tmpdir(tmpdir, &len);
|
||||||
|
ASSERT(r == UV_ENOBUFS);
|
||||||
|
ASSERT(len > SMALLPATH);
|
||||||
|
|
||||||
|
/* Test invalid inputs */
|
||||||
|
r = uv_os_tmpdir(NULL, &len);
|
||||||
|
ASSERT(r == UV_EINVAL);
|
||||||
|
r = uv_os_tmpdir(tmpdir, NULL);
|
||||||
|
ASSERT(r == UV_EINVAL);
|
||||||
|
len = 0;
|
||||||
|
r = uv_os_tmpdir(tmpdir, &len);
|
||||||
|
ASSERT(r == UV_EINVAL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
1
uv.gyp
1
uv.gyp
@ -387,6 +387,7 @@
|
|||||||
'test/test-threadpool.c',
|
'test/test-threadpool.c',
|
||||||
'test/test-threadpool-cancel.c',
|
'test/test-threadpool-cancel.c',
|
||||||
'test/test-thread-equal.c',
|
'test/test-thread-equal.c',
|
||||||
|
'test/test-tmpdir.c',
|
||||||
'test/test-mutexes.c',
|
'test/test-mutexes.c',
|
||||||
'test/test-thread.c',
|
'test/test-thread.c',
|
||||||
'test/test-barrier.c',
|
'test/test-barrier.c',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user