Mercurial > octave
view liboctave/util/oct-shlib.cc @ 32832:f3c1a77bcc6b
maint: Replace (void) in function declarations with () where possible
See: https://octave.discourse.group/t/remove-void-from-mex-cc-and-elsewhere/5221
Most instances of (void) that could be replaced with () have been replaced already.
This changeset is for some files that weren't covered previously.
The .c files and their headers are left untouched.
author | Arun Giridhar <arungiridhar@gmail.com> |
---|---|
date | Wed, 24 Jan 2024 19:31:35 -0500 |
parents | 4b601ca024d5 |
children |
line wrap: on
line source
//////////////////////////////////////////////////////////////////////// // // Copyright (C) 1999-2024 The Octave Project Developers // // See the file COPYRIGHT.md in the top-level directory of this // distribution or <https://octave.org/copyright/>. // // This file is part of Octave. // // Octave is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Octave is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Octave; see the file COPYING. If not, see // <https://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////// #if defined (HAVE_CONFIG_H) # include "config.h" #endif #include <list> #include <map> extern "C" { #if defined (HAVE_DLOPEN_API) # if defined (HAVE_DLFCN_H) # include <dlfcn.h> # else extern void * dlopen (const char *, int); extern const char * dlerror (); extern void * dlsym (void *, const char *); extern int dlclose (void *); # endif #elif defined (HAVE_LOADLIBRARY_API) # define WIN32_LEAN_AND_MEAN 1 # include <windows.h> # include <psapi.h> #endif } #include "file-ops.h" #include "file-stat.h" #include "lo-error.h" #include "oct-shlib.h" #include "str-vec.h" #if defined (HAVE_LOADLIBRARY_API) # include "lo-sysdep.h" #endif OCTAVE_BEGIN_NAMESPACE(octave) std::list<dynamic_library> possibly_unreferenced_dynamic_libraries; void dynamic_library::delete_later () { possibly_unreferenced_dynamic_libraries.push_back (*this); } int release_unreferenced_dynamic_libraries () { possibly_unreferenced_dynamic_libraries.clear (); return 0; } dynamic_library::dynlib_rep::dynlib_rep (const std::string& f) : m_count (1), m_fcn_names (), m_file (f), m_time_loaded (), m_search_all_loaded (false) { s_instances[f] = this; if (is_out_of_date ()) (*current_liboctave_warning_with_id_handler) ("Octave:future-time-stamp", "time stamp for file '%s' is in the future", m_file.c_str ()); } bool dynamic_library::dynlib_rep::is_out_of_date () const { sys::file_stat fs (m_file); return (fs && fs.is_newer (m_time_loaded)); } void dynamic_library::dynlib_rep::fake_reload () { // We can't actually reload the library, but we'll pretend we did. sys::file_stat fs (m_file); if (fs && fs.is_newer (m_time_loaded)) { m_time_loaded = fs.mtime (); (*current_liboctave_warning_with_id_handler) ("Octave:library-reload", "library %s not reloaded due to existing references", m_file.c_str ()); } } dynamic_library::dynlib_rep * dynamic_library::dynlib_rep::get_instance (const std::string& f, bool fake) { dynlib_rep *retval = nullptr; std::map<std::string, dynlib_rep *>::iterator p = s_instances.find (f); if (p != s_instances.end ()) { retval = p->second; retval->m_count++; if (fake) retval->fake_reload (); } else retval = new_instance (f); return retval; } std::list<std::string> dynamic_library::dynlib_rep::function_names () const { std::list<std::string> retval; for (const auto& p : m_fcn_names) retval.push_back (p.first); return retval; } void dynamic_library::dynlib_rep::add_fcn_name (const std::string& name) { auto p = m_fcn_names.find (name); if (p == m_fcn_names.end ()) m_fcn_names[name] = 1; else ++(p->second); } bool dynamic_library::dynlib_rep::remove_fcn_name (const std::string& fcn_name) { bool retval = false; auto p = m_fcn_names.find (fcn_name); if (p != m_fcn_names.end () && --(p->second) == 0) { m_fcn_names.erase (fcn_name); retval = true; } return retval; } std::map<std::string, dynamic_library::dynlib_rep *> dynamic_library::dynlib_rep::s_instances; dynamic_library::dynlib_rep dynamic_library::s_nil_rep; #if defined (HAVE_DLOPEN_API) class octave_dlopen_shlib : public dynamic_library::dynlib_rep { public: octave_dlopen_shlib (const std::string& f); OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (octave_dlopen_shlib) ~octave_dlopen_shlib (); void * search (const std::string& name, const dynamic_library::name_mangler& mangler = dynamic_library::name_mangler ()); // FIXME: this is possibly redundant because failure to open a library will // normally throw an exception, avoiding the construction of an invalid // library. Leave it here for possible future use. bool is_open () const { return (m_search_all_loaded || m_library != nullptr); } private: void *m_library; }; octave_dlopen_shlib::octave_dlopen_shlib (const std::string& f) : dynamic_library::dynlib_rep (f), m_library (nullptr) { int flags = 0; // Use RTLD_NOW to resolve all symbols before dlopen returns. // By using this option, dlopen will detect errors and Octave // won't exit if there are unresolved symbols in the file we are // loading, and we may even get a useful diagnostic. # if defined (RTLD_NOW) flags |= RTLD_NOW; # endif // Use RTLD_GLOBAL to export symbols from loaded objects so they are // available to other subsequently loaded libraries. # if defined (RTLD_GLOBAL) flags |= RTLD_GLOBAL; # endif if (m_file.empty ()) { m_search_all_loaded = true; return; } m_library = dlopen (m_file.c_str (), flags); if (! m_library) { const char *msg = dlerror (); if (msg) (*current_liboctave_error_handler) ("%s: failed to load\nIncompatible version or missing dependency?" "\n%s", m_file.c_str (), msg); else (*current_liboctave_error_handler) ("%s: failed to load\nIncompatible version or missing dependency?", m_file.c_str ()); } } octave_dlopen_shlib::~octave_dlopen_shlib () { if (m_library) dlclose (m_library); } void * octave_dlopen_shlib::search (const std::string& name, const dynamic_library::name_mangler& mangler) { void *function = nullptr; if (! is_open ()) (*current_liboctave_error_handler) ("shared library %s is not open", m_file.c_str ()); std::string sym_name = name; if (mangler) sym_name = mangler (name); if (m_search_all_loaded) function = dlsym (RTLD_DEFAULT, sym_name.c_str ()); else function = dlsym (m_library, sym_name.c_str ()); return function; } #elif defined (HAVE_LOADLIBRARY_API) class octave_w32_shlib: public dynamic_library::dynlib_rep { public: octave_w32_shlib (const std::string& f); OCTAVE_DISABLE_COPY_MOVE (octave_w32_shlib) ~octave_w32_shlib (); void * search (const std::string& name, const dynamic_library::name_mangler& mangler = dynamic_library::name_mangler ()); void * global_search (const std::string& sym_name); bool is_open () const { return (m_search_all_loaded || m_handle != nullptr); } private: HINSTANCE m_handle; }; octave_w32_shlib::octave_w32_shlib (const std::string& f) : dynamic_library::dynlib_rep (f), m_handle (nullptr) { if (f.empty()) { m_search_all_loaded = true; return; } std::string dir = sys::file_ops::dirname (f); std::wstring wdir = sys::u8_to_wstring (dir); SetDllDirectoryW (dir.empty () ? nullptr : wdir.c_str ()); std::wstring wfile = sys::u8_to_wstring (m_file); m_handle = LoadLibraryW (wfile.c_str ()); SetDllDirectoryW (nullptr); if (! m_handle) { DWORD last_error = GetLastError (); wchar_t *error_text = nullptr; FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, last_error, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast <wchar_t *> (&error_text), 0, nullptr); std::ostringstream err_str; err_str << "opening the library '" << m_file << "' failed (error " << last_error << "): "; if (error_text != nullptr) { err_str << sys::u8_from_wstring (error_text); LocalFree (error_text); } else err_str << "Unknown error."; (*current_liboctave_error_handler) ("%s", err_str.str ().c_str ()); } } octave_w32_shlib::~octave_w32_shlib () { if (m_handle) FreeLibrary (m_handle); } void * octave_w32_shlib::global_search (const std::string& sym_name) { void *function = nullptr; HANDLE proc = GetCurrentProcess (); if (! proc) (*current_liboctave_error_handler) ("Unable to get handle to own process."); std::size_t lib_num = 64; std::size_t size_lib = sizeof (HMODULE); HMODULE *h_libs; DWORD bytes_all_libs; bool got_libs; // Get a list of all the libraries in own process. h_libs = static_cast<HMODULE *> (malloc (size_lib*lib_num)); got_libs = EnumProcessModules (proc, h_libs, size_lib*lib_num, &bytes_all_libs); int ii = 0; while (((size_lib*lib_num) < bytes_all_libs) && ii++ < 3) { lib_num = bytes_all_libs / size_lib; h_libs = static_cast<HMODULE *> (realloc (h_libs, bytes_all_libs)); got_libs = EnumProcessModules (proc, h_libs, bytes_all_libs, &bytes_all_libs); } if (got_libs) { for (std::size_t i = 0; i < (bytes_all_libs / size_lib); i++) { // Check for function in library. function = reinterpret_cast<void *> (GetProcAddress (h_libs[i], sym_name.c_str ())); if (function) break; } } // Release the handle to the process. CloseHandle (proc); return function; } void * octave_w32_shlib::search (const std::string& name, const dynamic_library::name_mangler& mangler) { void *function = nullptr; if (! m_search_all_loaded && ! is_open ()) (*current_liboctave_error_handler) ("shared library %s is not open", m_file.c_str ()); std::string sym_name = name; if (mangler) sym_name = mangler (name); if (m_search_all_loaded) function = global_search (sym_name); else function = reinterpret_cast<void *> (GetProcAddress (m_handle, sym_name.c_str ())); return function; } #endif dynamic_library::dynlib_rep * dynamic_library::dynlib_rep::new_instance (const std::string& f) { #if defined (HAVE_DLOPEN_API) return new octave_dlopen_shlib (f); #elif defined (HAVE_LOADLIBRARY_API) return new octave_w32_shlib (f); #else (*current_liboctave_error_handler) ("support for dynamically loaded libraries was unavailable or disabled when liboctave was built"); #endif } OCTAVE_END_NAMESPACE(octave)