@@ -63,7 +63,6 @@ typedef int mode_t;
63
63
#endif
64
64
65
65
#ifdef __POSIX__
66
- # include < dlfcn.h> /* dlopen(), dlsym() */
67
66
# include < pwd.h> /* getpwnam() */
68
67
# include < grp.h> /* getgrnam() */
69
68
#endif
@@ -1642,73 +1641,84 @@ Handle<Value> Kill(const Arguments& args) {
1642
1641
return Undefined ();
1643
1642
}
1644
1643
1644
+ #endif // __POSIX__
1645
+
1645
1646
1646
- typedef void (* extInit)(Handle<Object> exports);
1647
+ typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
1647
1648
1648
1649
// DLOpen is node.dlopen(). Used to load 'module.node' dynamically shared
1649
1650
// objects.
1650
1651
Handle<Value> DLOpen (const v8::Arguments& args) {
1651
- node_module_struct compat_mod;
1652
1652
HandleScope scope;
1653
+ char symbol[1024 ], *base, *pos;
1654
+ uv_lib_t lib;
1655
+ node_module_struct compat_mod;
1656
+ uv_err_t err;
1657
+ int r;
1653
1658
1654
- if (args.Length () < 2 ) return Undefined ();
1659
+ if (args.Length () < 2 ) {
1660
+ return Undefined ();
1661
+ }
1655
1662
1656
1663
String::Utf8Value filename (args[0 ]->ToString ()); // Cast
1657
1664
Local<Object> target = args[1 ]->ToObject (); // Cast
1658
1665
1659
- // Actually call dlopen().
1660
- // FIXME: This is a blocking function and should be called asynchronously!
1661
- // This function should be moved to file.cc and use libeio to make this
1662
- // system call.
1663
- void *handle = dlopen (*filename, RTLD_LAZY);
1664
-
1665
- // Handle errors.
1666
- if (handle == NULL ) {
1667
- Local<Value> exception = Exception::Error (String::New (dlerror ()));
1668
- return ThrowException (exception);
1666
+ err = uv_dlopen (*filename, &lib);
1667
+ if (err.code != UV_OK) {
1668
+ SetErrno (err);
1669
+ return scope.Close (Integer::New (-1 ));
1669
1670
}
1670
1671
1671
- String::Utf8Value symbol (args[0 ]->ToString ());
1672
- char *symstr = NULL ;
1673
- {
1674
- char *sym = *symbol;
1675
- char *p = strrchr (sym, ' /' );
1676
- if (p != NULL ) {
1677
- sym = p+1 ;
1678
- }
1672
+ String::Utf8Value path (args[0 ]->ToString ());
1673
+ base = *path;
1679
1674
1680
- p = strrchr (sym, ' .' );
1681
- if (p != NULL ) {
1682
- *p = ' \0 ' ;
1675
+ /* Find the shared library filename within the full path. */
1676
+ #ifdef __POSIX__
1677
+ pos = strrchr (base, ' /' );
1678
+ if (pos != NULL ) {
1679
+ base = pos;
1680
+ }
1681
+ #else // Windows
1682
+ for (;;) {
1683
+ pos = strpbrk (base, " \\ /:" );
1684
+ if (pos == NULL ) {
1685
+ break ;
1683
1686
}
1687
+ base = pos + 1 ;
1688
+ }
1689
+ #endif
1690
+
1691
+ /* Strip the .node extension. */
1692
+ pos = strrchr (base, ' .' );
1693
+ if (pos != NULL ) {
1694
+ *pos = ' \0 ' ;
1695
+ }
1684
1696
1685
- size_t slen = strlen (sym);
1686
- symstr = static_cast <char *>(calloc (1 , slen + sizeof (" _module" ) + 1 ));
1687
- memcpy (symstr, sym, slen);
1688
- memcpy (symstr+slen, " _module" , sizeof (" _module" ) + 1 );
1697
+ /* Add the `_module` suffix to the extension name. */
1698
+ r = snprintf (symbol, sizeof symbol, " %s_module" , base);
1699
+ if (r <= 0 || r >= sizeof symbol) {
1700
+ err.code = UV_ENOMEM;
1701
+ SetErrno (err);
1702
+ return scope.Close (Integer::New (-1 ));
1689
1703
}
1690
1704
1691
1705
// Get the init() function from the dynamically shared object.
1692
- node_module_struct *mod = static_cast <node_module_struct *>(dlsym (handle, symstr));
1693
- free (symstr);
1694
- symstr = NULL ;
1706
+ node_module_struct *mod;
1707
+ err = uv_dlsym (lib, symbol, reinterpret_cast <void **>(&mod));
1695
1708
1696
- // Error out if not found.
1697
- if (mod == NULL ) {
1709
+ if (err.code != UV_OK) {
1698
1710
/* Start Compatibility hack: Remove once everyone is using NODE_MODULE macro */
1699
1711
memset (&compat_mod, 0 , sizeof compat_mod);
1700
1712
1701
1713
mod = &compat_mod;
1702
1714
mod->version = NODE_MODULE_VERSION;
1703
1715
1704
- void *init_handle = dlsym (handle, " init" );
1705
- if (init_handle == NULL ) {
1706
- dlclose (handle);
1707
- Local<Value> exception =
1708
- Exception::Error (String::New (" No module symbol found in module." ));
1709
- return ThrowException (exception);
1716
+ err = uv_dlsym (lib, " init" , reinterpret_cast <void **>(&mod->register_func ));
1717
+ if (err.code != UV_OK) {
1718
+ uv_dlclose (lib);
1719
+ SetErrno (err);
1720
+ return scope.Close (Integer::New (-1 ));
1710
1721
}
1711
- mod->register_func = (extInit)(init_handle);
1712
1722
/* End Compatibility hack */
1713
1723
}
1714
1724
@@ -1726,8 +1736,6 @@ Handle<Value> DLOpen(const v8::Arguments& args) {
1726
1736
return Undefined ();
1727
1737
}
1728
1738
1729
- #endif // __POSIX__
1730
-
1731
1739
1732
1740
// TODO remove me before 0.4
1733
1741
Handle<Value> Compile (const Arguments& args) {
@@ -2161,10 +2169,11 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
2161
2169
NODE_SET_METHOD (process, " setgid" , SetGid);
2162
2170
NODE_SET_METHOD (process, " getgid" , GetGid);
2163
2171
2164
- NODE_SET_METHOD (process, " dlopen" , DLOpen);
2165
2172
NODE_SET_METHOD (process, " _kill" , Kill);
2166
2173
#endif // __POSIX__
2167
2174
2175
+ NODE_SET_METHOD (process, " dlopen" , DLOpen);
2176
+
2168
2177
NODE_SET_METHOD (process, " uptime" , Uptime);
2169
2178
NODE_SET_METHOD (process, " memoryUsage" , MemoryUsage);
2170
2179
NODE_SET_METHOD (process, " uvCounters" , UVCounters);
0 commit comments