@@ -104,6 +104,15 @@ namespace boost { namespace dll { namespace detail {
104
104
#if BOOST_OS_QNX
105
105
// QNX's copy of <elf.h> and <link.h> reside in sys folder
106
106
# include < sys/link.h>
107
+ #elif BOOST_OS_CYGWIN
108
+ // Cygwin returns the opaque pointer-sized handle of type `HMODULE` on the invoke of `dlopen`,
109
+ // which cannot be interpreted. As GCC on Cygwin always links to KERNEL32.DLL, we can use the
110
+ // standard Win32 API `GetModuleFileNameW` to implement `path_from_handle`
111
+ //
112
+ // Introduce the Win32 API `GetModuleFileNameW` here
113
+ extern " C" void GetModuleFileNameW (void *, wchar_t *, unsigned long long );
114
+ // Introduce the Win32 API `GetLastError` here
115
+ extern " C" unsigned long long GetLastError ();
107
116
#else
108
117
# include < link.h> // struct link_map
109
118
#endif
@@ -129,9 +138,29 @@ namespace boost { namespace dll { namespace detail {
129
138
// Unfortunately we can not use `dlinfo(handle, RTLD_DI_LINKMAP, &link_map) < 0`
130
139
// because it is not supported on MacOS X 10.3, NetBSD 3.0, OpenBSD 3.8, AIX 5.1,
131
140
// HP-UX 11, IRIX 6.5, OSF/1 5.1, Cygwin, mingw, Interix 3.5, BeOS.
132
- // Fortunately investigating the sources of open source projects brought the understanding, that
141
+ // Fortunately, investigating the sources of open source projects brought the understanding, that
133
142
// `handle` is just a `struct link_map*` that contains full library name.
134
143
144
+ #if BOOST_OS_CYGWIN
145
+ // Cygwin doesn't have <link.h> header
146
+ unsigned long long buffer_size = 4096 ;
147
+ std::vector<wchar_t > buffer;
148
+ do
149
+ {
150
+ buffer.resize (buffer_size);
151
+ GetModuleFileNameW (handle, buffer.data (), buffer.size ());
152
+ buffer_size *= 2 ;
153
+ } while (GetLastError () == 122 /* ERROR_INSUFFICIENT_BUFFER */ );
154
+ if (GetLastError () == 0 )
155
+ {
156
+ return boost::filesystem::path (buffer.data ());
157
+ } else
158
+ {
159
+ boost::dll::detail::reset_dlerror ();
160
+ ec = std::make_error_code (std::errc::bad_file_descriptor);
161
+ return boost::filesystem::path ();
162
+ }
163
+ #else
135
164
const struct link_map * link_map = 0 ;
136
165
#if BOOST_OS_BSD_FREE
137
166
// FreeBSD has it's own logic http://code.metager.de/source/xref/freebsd/libexec/rtld-elf/rtld.c
@@ -156,6 +185,7 @@ namespace boost { namespace dll { namespace detail {
156
185
}
157
186
158
187
return boost::dll::fs::path (link_map->l_name );
188
+ #endif
159
189
}
160
190
161
191
}}} // namespace boost::dll::detail
0 commit comments