Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

win, unix: add uv_dlerror() and uv_dlerror_free()

  • Loading branch information...
commit b55801f2254b8830f4cd3e06741c9546d35284f8 1 parent 702f905
@shigeki shigeki authored bnoordhuis committed
View
2  config-unix.mk
@@ -116,6 +116,8 @@ endif
RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE
RUNNER_LINKFLAGS=$(LINKFLAGS)
+RUNNER_LINKFLAGS += -ldl
+
ifeq (SunOS,$(uname_S))
RUNNER_LINKFLAGS += -pthreads
else
View
6 include/uv.h
@@ -1400,6 +1400,12 @@ UV_EXTERN uv_err_t uv_dlclose(uv_lib_t library);
UV_EXTERN uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr);
/*
+ * Retrieves and frees an error message of dynamic linking loaders.
+ */
+UV_EXTERN const char *uv_dlerror(uv_lib_t library);
+UV_EXTERN void uv_dlerror_free(uv_lib_t library, const char *msg);
+
+/*
* The mutex functions return 0 on success, -1 on error
* (unless the return type is void, of course).
*/
View
22 src/unix/dl.c
@@ -24,6 +24,8 @@
#include <dlfcn.h>
#include <errno.h>
+#include <string.h>
+#include <locale.h>
/* The dl family of functions don't set errno. We need a good way to communicate
* errors to the caller but there is only dlerror() and that returns a string -
@@ -67,3 +69,23 @@ uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr) {
*ptr = (void*) address;
return uv_ok_;
}
+
+
+const char *uv_dlerror(uv_lib_t library) {
+ const char* buf = NULL;
+ /* Make uv_dlerror() be independent of locale */
+ char* loc = setlocale(LC_MESSAGES, NULL);
+ if(strcmp(loc, "C") == 0) {
+ return strdup(dlerror());
+ } else {
+ setlocale(LC_MESSAGES, "C");
+ buf = dlerror();
+ setlocale(LC_MESSAGES, loc);
+ return strdup(buf);
+ }
+}
+
+
+void uv_dlerror_free(uv_lib_t library, const char *msg) {
+ free((void*)msg);
+}
View
27 src/win/dl.c
@@ -22,6 +22,7 @@
#include "uv.h"
#include "internal.h"
+__declspec( thread ) DWORD saved_errno = 0;
uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
wchar_t filename_w[32768];
@@ -30,12 +31,14 @@ uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
if (!uv_utf8_to_utf16(filename,
filename_w,
sizeof(filename_w) / sizeof(wchar_t))) {
- return uv__new_sys_error(GetLastError());
+ saved_errno = GetLastError();
+ return uv__new_sys_error(saved_errno);
}
handle = LoadLibraryW(filename_w);
if (handle == NULL) {
- return uv__new_sys_error(GetLastError());
+ saved_errno = GetLastError();
+ return uv__new_sys_error(saved_errno);
}
*library = handle;
@@ -45,7 +48,8 @@ uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
uv_err_t uv_dlclose(uv_lib_t library) {
if (!FreeLibrary(library)) {
- return uv__new_sys_error(GetLastError());
+ saved_errno = GetLastError();
+ return uv__new_sys_error(saved_errno);
}
return uv_ok_;
@@ -55,9 +59,24 @@ uv_err_t uv_dlclose(uv_lib_t library) {
uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr) {
FARPROC proc = GetProcAddress(library, name);
if (proc == NULL) {
- return uv__new_sys_error(GetLastError());
+ saved_errno = GetLastError();
+ return uv__new_sys_error(saved_errno);
}
*ptr = (void*) proc;
return uv_ok_;
}
+
+
+const char *uv_dlerror(uv_lib_t library) {
+ char* buf = NULL;
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, saved_errno,
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPSTR)&buf, 0, NULL);
+ return buf;
+}
+
+
+void uv_dlerror_free(uv_lib_t library, const char *msg) {
+ LocalFree((LPVOID)msg);
+}
View
1  test/fixtures/load_error.node
@@ -0,0 +1 @@
+foobar
View
49 test/test-dlerror.c
@@ -0,0 +1,49 @@
+/* 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>
+
+const char* path = "test/fixtures/load_error.node";
+const char* msg;
+
+#ifdef __linux__
+ const char* dlerror_desc = "file too short";
+#elif defined (__sun__)
+ const char* dlerror_desc = "unknown file type";
+#elif defined (_WIN32)
+ const char* dlerror_desc = "%1 is not a valid Win32 application";
+#else
+ const char* dlerror_desc = "";
+#endif
+
+uv_lib_t lib;
+uv_err_t r;
+
+TEST_IMPL(dlerror) {
+ r = uv_dlopen(path, &lib);
+ msg = uv_dlerror(lib);
+ ASSERT(msg != NULL);
+ ASSERT(strstr(msg, dlerror_desc) != NULL);
+ uv_dlerror_free(lib, msg);
+ return 0;
+}
View
2  test/test-list.h
@@ -142,6 +142,7 @@ TEST_DECLARE (thread_create)
TEST_DECLARE (strlcpy)
TEST_DECLARE (strlcat)
TEST_DECLARE (counters_init)
+TEST_DECLARE (dlerror)
#ifdef _WIN32
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
TEST_DECLARE (argument_escaping)
@@ -326,6 +327,7 @@ TASK_LIST_START
TEST_ENTRY (strlcpy)
TEST_ENTRY (strlcat)
TEST_ENTRY (counters_init)
+ TEST_ENTRY (dlerror)
#if 0
/* These are for testing the test runner. */
TEST_ENTRY (fail_always)
View
1  uv.gyp
@@ -338,6 +338,7 @@
'test/test-udp-send-and-recv.c',
'test/test-udp-multicast-join.c',
'test/test-counters-init.c',
+ 'test/test-dlerror.c',
'test/test-udp-multicast-ttl.c',
],
'conditions': [
Please sign in to comment.
Something went wrong with that request. Please try again.