From dceb3e65cafdfce9cc931c285d6e742e74ac7cc9 Mon Sep 17 00:00:00 2001 From: Igor Zinkovsky Date: Wed, 30 Nov 2011 15:31:39 -0800 Subject: [PATCH] uv_cwd + uv_chdir --- include/uv.h | 6 +++ src/unix/core.c | 22 ++++++++++ src/win/util.c | 86 +++++++++++++++++++++++++++++++++++++++ test/test-cwd-and-chdir.c | 61 +++++++++++++++++++++++++++ test/test-list.h | 3 ++ uv.gyp | 1 + 6 files changed, 179 insertions(+) create mode 100644 test/test-cwd-and-chdir.c diff --git a/include/uv.h b/include/uv.h index 5fde249e..ea845e3a 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1213,6 +1213,12 @@ UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size); /* Gets the executable path */ UV_EXTERN int uv_exepath(char* buffer, size_t* size); +/* Gets the current working directory */ +UV_EXTERN uv_err_t uv_cwd(char* buffer, size_t size); + +/* Changes the current working directory */ +UV_EXTERN uv_err_t uv_chdir(const char* dir); + /* Gets memory info in bytes */ UV_EXTERN uint64_t uv_get_free_memory(void); UV_EXTERN uint64_t uv_get_total_memory(void); diff --git a/src/unix/core.c b/src/unix/core.c index 4d832413..7978e1bb 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -845,3 +845,25 @@ size_t uv__strlcpy(char* dst, const char* src, size_t size) { return src - org; } + + +uv_err_t uv_cwd(char* buffer, size_t size) { + if (!buffer || !size) { + return uv__new_artificial_error(UV_EINVAL); + } + + if (getcwd(buffer, size)) { + return uv_ok_; + } else { + return uv__new_sys_error(errno); + } +} + + +uv_err_t uv_chdir(const char* dir) { + if (chdir(dir) == 0) { + return uv_ok_; + } else { + return uv__new_sys_error(errno); + } +} diff --git a/src/win/util.c b/src/win/util.c index 3bc3e1db..ece56611 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -20,6 +20,7 @@ */ #include +#include #include #include @@ -97,6 +98,91 @@ done: } +uv_err_t uv_cwd(char* buffer, size_t size) { + uv_err_t err; + size_t utf8Size; + wchar_t* utf16Buffer = NULL; + + if (!buffer || !size) { + err.code = UV_EINVAL; + goto done; + } + + utf16Buffer = (wchar_t*)malloc(sizeof(wchar_t) * size); + if (!utf16Buffer) { + err.code = UV_ENOMEM; + goto done; + } + + if (!_wgetcwd(utf16Buffer, size - 1)) { + err = uv__new_sys_error(_doserrno); + goto done; + } + + utf16Buffer[size - 1] = L'\0'; + + /* Convert to UTF-8 */ + utf8Size = uv_utf16_to_utf8(utf16Buffer, -1, buffer, size); + if (utf8Size == 0) { + err = uv__new_sys_error(GetLastError()); + goto done; + } + + buffer[utf8Size] = '\0'; + err = uv_ok_; + +done: + if (utf16Buffer) { + free(utf16Buffer); + } + + return err; +} + + +uv_err_t uv_chdir(const char* dir) { + uv_err_t err; + wchar_t* utf16Buffer = NULL; + size_t utf16Size; + + if (!dir) { + err.code = UV_EINVAL; + goto done; + } + + utf16Size = uv_utf8_to_utf16(dir, NULL, 0); + if (!utf16Size) { + err = uv__new_sys_error(GetLastError()); + goto done; + } + + utf16Buffer = (wchar_t*)malloc(sizeof(wchar_t) * utf16Size); + if (!utf16Buffer) { + err.code = UV_ENOMEM; + goto done; + } + + if (!uv_utf8_to_utf16(dir, utf16Buffer, utf16Size)) { + err = uv__new_sys_error(GetLastError()); + goto done; + } + + if (_wchdir(utf16Buffer) == -1) { + err = uv__new_sys_error(_doserrno); + goto done; + } + + err = uv_ok_; + +done: + if (utf16Buffer) { + free(utf16Buffer); + } + + return err; +} + + void uv_loadavg(double avg[3]) { /* Can't be implemented */ avg[0] = avg[1] = avg[2] = 0; diff --git a/test/test-cwd-and-chdir.c b/test/test-cwd-and-chdir.c new file mode 100644 index 00000000..deafdc94 --- /dev/null +++ b/test/test-cwd-and-chdir.c @@ -0,0 +1,61 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#define PATHMAX 1024 +extern char executable_path[]; + +TEST_IMPL(cwd_and_chdir) { + char buffer_orig[PATHMAX]; + char buffer_new[PATHMAX]; + size_t size; + char* last_slash; + uv_err_t err; + + size = sizeof(buffer_orig) / sizeof(buffer_orig[0]); + err = uv_cwd(buffer_orig, size); + ASSERT(err.code == UV_OK); + + last_slash = strrchr(buffer_orig, +#ifdef _WIN32 + '\\' +#else + '/' +#endif + ); + + ASSERT(last_slash); + + *last_slash = '\0'; + + err = uv_chdir(buffer_orig); + ASSERT(err.code == UV_OK); + + err = uv_cwd(buffer_new, size); + ASSERT(err.code == UV_OK); + + ASSERT(strcmp(buffer_orig, buffer_new) == 0); + + return 0; +} diff --git a/test/test-list.h b/test/test-list.h index d6639df0..fbd23d6c 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -77,6 +77,7 @@ TEST_DECLARE (check_ref) TEST_DECLARE (unref_in_prepare_cb) TEST_DECLARE (async) TEST_DECLARE (get_currentexe) +TEST_DECLARE (cwd_and_chdir) TEST_DECLARE (get_memory) TEST_DECLARE (hrtime) TEST_DECLARE (getaddrinfo_basic) @@ -216,6 +217,8 @@ TASK_LIST_START TEST_ENTRY (get_currentexe) + TEST_ENTRY (cwd_and_chdir) + TEST_ENTRY (get_memory) TEST_ENTRY (get_loadavg) diff --git a/uv.gyp b/uv.gyp index 83129b5c..fae7263a 100644 --- a/uv.gyp +++ b/uv.gyp @@ -278,6 +278,7 @@ 'test/test-error.c', 'test/test-callback-stack.c', 'test/test-connection-fail.c', + 'test/test-cwd-and-chdir.c', 'test/test-delayed-accept.c', 'test/test-fail-always.c', 'test/test-fs.c',