mirror of
https://github.com/libuv/libuv
synced 2025-03-28 21:13:16 +00:00
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-from-check.c \
|
||||
test/test-timer.c \
|
||||
test/test-tmpdir.c \
|
||||
test/test-tty.c \
|
||||
test/test-udp-bind.c \
|
||||
test/test-udp-create-socket-early.c \
|
||||
|
@ -155,6 +155,7 @@ test/test-threadpool-cancel.c
|
||||
test/test-threadpool.c
|
||||
test/test-timer-again.c
|
||||
test/test-timer.c
|
||||
test/test-tmpdir.c
|
||||
test/test-tty.c
|
||||
test/test-udp-dgram-too-big.c
|
||||
test/test-udp-ipv6.c
|
||||
|
@ -273,6 +273,22 @@ API
|
||||
|
||||
.. 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)
|
||||
.. 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_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 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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
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 (handle_fileno)
|
||||
TEST_DECLARE (homedir)
|
||||
TEST_DECLARE (tmpdir)
|
||||
TEST_DECLARE (hrtime)
|
||||
TEST_DECLARE (getaddrinfo_fail)
|
||||
TEST_DECLARE (getaddrinfo_fail_sync)
|
||||
@ -586,6 +587,8 @@ TASK_LIST_START
|
||||
|
||||
TEST_ENTRY (homedir)
|
||||
|
||||
TEST_ENTRY (tmpdir)
|
||||
|
||||
TEST_ENTRY (hrtime)
|
||||
|
||||
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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user