Skip to content

Instantly share code, notes, and snippets.

@igorzi
Created November 30, 2011 23:32
Show Gist options
  • Save igorzi/1411882 to your computer and use it in GitHub Desktop.
Save igorzi/1411882 to your computer and use it in GitHub Desktop.
From 9839d0a6d42d3dd406bd4c35aef7e07b84d11147 Mon Sep 17 00:00:00 2001
From: Igor Zinkovsky <igorzi@microsoft.com>
Date: Wed, 30 Nov 2011 15:31:39 -0800
Subject: [PATCH] uv_cwd + uv_chdir
---
include/uv.h | 6 +++
src/unix/core.c | 18 +++++++++
src/win/util.c | 86 +++++++++++++++++++++++++++++++++++++++++++++
test/test-cwd-and-chdir.c | 61 ++++++++++++++++++++++++++++++++
test/test-list.h | 3 ++
uv.gyp | 1 +
6 files changed, 175 insertions(+), 0 deletions(-)
create mode 100644 test/test-cwd-and-chdir.c
diff --git a/include/uv.h b/include/uv.h
index 2710518..a889310 100644
--- a/include/uv.h
+++ b/include/uv.h
@@ -1214,6 +1214,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, const 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 4d83241..2a2ea61 100644
--- a/src/unix/core.c
+++ b/src/unix/core.c
@@ -845,3 +845,21 @@ size_t uv__strlcpy(char* dst, const char* src, size_t size) {
return src - org;
}
+
+
+uv_err_t uv_cwd(char* buffer, const size_t size) {
+ 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 3bc3e1d..2eefdb7 100644
--- a/src/win/util.c
+++ b/src/win/util.c
@@ -20,6 +20,7 @@
*/
#include <assert.h>
+#include <direct.h>
#include <malloc.h>
#include <string.h>
@@ -97,6 +98,91 @@ done:
}
+uv_err_t uv_cwd(char* buffer, const 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 0000000..deafdc9
--- /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 <string.h>
+
+#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 d6639df..fbd23d6 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 88cee32..efca374 100644
--- a/uv.gyp
+++ b/uv.gyp
@@ -281,6 +281,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',
--
1.7.4.msysgit.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment