EIO_CONFIG=config_linux.h
CSTDFLAG += -D_GNU_SOURCE
CPPFLAGS += -Isrc/ares/config_linux
-LINKFLAGS+=-lrt
+LINKFLAGS+=-ldl -lrt
OBJS += src/unix/linux/core.o src/unix/linux/inotify.o
endif
*/
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).
assert(uv__timer_active(timer));
- assert(uv__timer_active(timer));
-
if (!uv__timer_repeating(timer)) {
timer->flags &= ~UV_TIMER_ACTIVE;
ev_ref(EV_A);
#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 -
*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);
+}
#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];
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;
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_;
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);
+}
time.tm_hour = system_time.wHour;
time.tm_min = system_time.wMinute;
time.tm_sec = system_time.wSecond;
- time.tm_isdst = -1;
*stat_time = mktime(&time);
} else {
--- /dev/null
+/* 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;
+}
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)
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)
],
'direct_dependent_settings': {
'include_dirs': [ 'include' ],
+ 'conditions': [
+ ['OS=="linux"', {
+ 'libraries': [ '-ldl' ],
+ }],
+ ],
},
'defines': [
'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': [