win, unix: add uv_dlerror() and uv_dlerror_free()
This commit is contained in:
parent
702f905f73
commit
b55801f225
@ -116,6 +116,8 @@ endif
|
|||||||
RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE
|
RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE
|
||||||
RUNNER_LINKFLAGS=$(LINKFLAGS)
|
RUNNER_LINKFLAGS=$(LINKFLAGS)
|
||||||
|
|
||||||
|
RUNNER_LINKFLAGS += -ldl
|
||||||
|
|
||||||
ifeq (SunOS,$(uname_S))
|
ifeq (SunOS,$(uname_S))
|
||||||
RUNNER_LINKFLAGS += -pthreads
|
RUNNER_LINKFLAGS += -pthreads
|
||||||
else
|
else
|
||||||
|
|||||||
@ -1399,6 +1399,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);
|
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
|
* The mutex functions return 0 on success, -1 on error
|
||||||
* (unless the return type is void, of course).
|
* (unless the return type is void, of course).
|
||||||
|
|||||||
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <errno.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
|
/* 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 -
|
* 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;
|
*ptr = (void*) address;
|
||||||
return uv_ok_;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
27
src/win/dl.c
27
src/win/dl.c
@ -22,6 +22,7 @@
|
|||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
__declspec( thread ) DWORD saved_errno = 0;
|
||||||
|
|
||||||
uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
|
uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
|
||||||
wchar_t filename_w[32768];
|
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,
|
if (!uv_utf8_to_utf16(filename,
|
||||||
filename_w,
|
filename_w,
|
||||||
sizeof(filename_w) / sizeof(wchar_t))) {
|
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);
|
handle = LoadLibraryW(filename_w);
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
return uv__new_sys_error(GetLastError());
|
saved_errno = GetLastError();
|
||||||
|
return uv__new_sys_error(saved_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
*library = handle;
|
*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) {
|
uv_err_t uv_dlclose(uv_lib_t library) {
|
||||||
if (!FreeLibrary(library)) {
|
if (!FreeLibrary(library)) {
|
||||||
return uv__new_sys_error(GetLastError());
|
saved_errno = GetLastError();
|
||||||
|
return uv__new_sys_error(saved_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
return uv_ok_;
|
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) {
|
uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr) {
|
||||||
FARPROC proc = GetProcAddress(library, name);
|
FARPROC proc = GetProcAddress(library, name);
|
||||||
if (proc == NULL) {
|
if (proc == NULL) {
|
||||||
return uv__new_sys_error(GetLastError());
|
saved_errno = GetLastError();
|
||||||
|
return uv__new_sys_error(saved_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
*ptr = (void*) proc;
|
*ptr = (void*) proc;
|
||||||
return uv_ok_;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
1
test/fixtures/load_error.node
vendored
Normal file
1
test/fixtures/load_error.node
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
foobar
|
||||||
49
test/test-dlerror.c
Normal file
49
test/test-dlerror.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
@ -142,6 +142,7 @@ TEST_DECLARE (thread_create)
|
|||||||
TEST_DECLARE (strlcpy)
|
TEST_DECLARE (strlcpy)
|
||||||
TEST_DECLARE (strlcat)
|
TEST_DECLARE (strlcat)
|
||||||
TEST_DECLARE (counters_init)
|
TEST_DECLARE (counters_init)
|
||||||
|
TEST_DECLARE (dlerror)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
|
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
|
||||||
TEST_DECLARE (argument_escaping)
|
TEST_DECLARE (argument_escaping)
|
||||||
@ -326,6 +327,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (strlcpy)
|
TEST_ENTRY (strlcpy)
|
||||||
TEST_ENTRY (strlcat)
|
TEST_ENTRY (strlcat)
|
||||||
TEST_ENTRY (counters_init)
|
TEST_ENTRY (counters_init)
|
||||||
|
TEST_ENTRY (dlerror)
|
||||||
#if 0
|
#if 0
|
||||||
/* These are for testing the test runner. */
|
/* These are for testing the test runner. */
|
||||||
TEST_ENTRY (fail_always)
|
TEST_ENTRY (fail_always)
|
||||||
|
|||||||
1
uv.gyp
1
uv.gyp
@ -338,6 +338,7 @@
|
|||||||
'test/test-udp-send-and-recv.c',
|
'test/test-udp-send-and-recv.c',
|
||||||
'test/test-udp-multicast-join.c',
|
'test/test-udp-multicast-join.c',
|
||||||
'test/test-counters-init.c',
|
'test/test-counters-init.c',
|
||||||
|
'test/test-dlerror.c',
|
||||||
'test/test-udp-multicast-ttl.c',
|
'test/test-udp-multicast-ttl.c',
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user