diff --git a/include/boost/dll/detail/posix/program_location_impl.hpp b/include/boost/dll/detail/posix/program_location_impl.hpp index 58544fa0..177e89fb 100644 --- a/include/boost/dll/detail/posix/program_location_impl.hpp +++ b/include/boost/dll/detail/posix/program_location_impl.hpp @@ -18,6 +18,7 @@ #if BOOST_OS_MACOS || BOOST_OS_IOS +#include #include namespace boost { namespace dll { namespace detail { @@ -29,16 +30,15 @@ namespace boost { namespace dll { namespace detail { if (_NSGetExecutablePath(path, &size) == 0) return boost::dll::fs::path(path); - char *p = new char[size]; - if (_NSGetExecutablePath(p, &size) != 0) { + std::string p; + p.resize(size); + if (_NSGetExecutablePath(p.data(), &size) != 0) { ec = std::make_error_code( std::errc::bad_file_descriptor ); } - boost::dll::fs::path ret(p); - delete[] p; - return ret; + return boost::dll::fs::path(std::move(p)); } }}} // namespace boost::dll::detail @@ -55,6 +55,7 @@ namespace boost { namespace dll { namespace detail { #elif BOOST_OS_BSD_FREE +#include #include #include #include @@ -68,11 +69,27 @@ namespace boost { namespace dll { namespace detail { mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; - char buf[10240]; - size_t cb = sizeof(buf); - sysctl(mib, 4, buf, &cb, NULL, 0); + char path[1024]; + size_t size = sizeof(buf); + if (sysctl(mib, 4, path, &size, nullptr, 0) == 0) + return boost::dll::fs::path(path); + + const auto errno_snapshot = static_cast(errno); + if (errno_snapshot != std::errc::not_enough_memory) { + ec = std::make_error_code( + errno_snapshot + ); + } + + std::string p; + p.resize(size); + if (sysctl(mib, 4, p.data(), &size, nullptr, 0) != 0) { + ec = std::make_error_code( + static_cast(errno) + ); + } - return boost::dll::fs::path(buf); + return boost::dll::fs::path(std::move(p)); } }}} // namespace boost::dll::detail @@ -103,17 +120,17 @@ namespace boost { namespace dll { namespace detail { inline boost::dll::fs::path program_location_impl(std::error_code &ec) { ec.clear(); - std::string s; + std::string path; std::ifstream ifs("/proc/self/exefile"); - std::getline(ifs, s); + std::getline(ifs, path); - if (ifs.fail() || s.empty()) { + if (ifs.fail() || path.empty()) { ec = std::make_error_code( std::errc::bad_file_descriptor ); } - return boost::dll::fs::path(s); + return boost::dll::fs::path(std::move(path)); } }}} // namespace boost::dll::detail diff --git a/include/boost/dll/detail/windows/path_from_handle.hpp b/include/boost/dll/detail/windows/path_from_handle.hpp index 505cd32f..24ca165b 100644 --- a/include/boost/dll/detail/windows/path_from_handle.hpp +++ b/include/boost/dll/detail/windows/path_from_handle.hpp @@ -28,8 +28,8 @@ namespace boost { namespace dll { namespace detail { } inline boost::dll::fs::path path_from_handle(boost::winapi::HMODULE_ handle, std::error_code &ec) { - BOOST_STATIC_CONSTANT(boost::winapi::DWORD_, ERROR_INSUFFICIENT_BUFFER_ = 0x7A); - BOOST_STATIC_CONSTANT(boost::winapi::DWORD_, DEFAULT_PATH_SIZE_ = 260); + constexpr boost::winapi::DWORD_ ERROR_INSUFFICIENT_BUFFER_ = 0x7A; + constexpr boost::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 260; // If `handle` parameter is NULL, GetModuleFileName retrieves the path of the // executable file of the current process. diff --git a/test/shared_library_load_test.cpp b/test/shared_library_load_test.cpp index ca22c7dd..0bb6068b 100644 --- a/test/shared_library_load_test.cpp +++ b/test/shared_library_load_test.cpp @@ -139,7 +139,14 @@ int main(int argc, char* argv[]) BOOST_TEST(sl2.location(ec) != sl.location()); BOOST_TEST(ec); } - + { + shared_library sl_empty(nullptr); + BOOST_TEST(!sl_empty.is_loaded()); + BOOST_TEST(!sl_empty); + std::error_code ec; + sl_empty.location(ec); + BOOST_TEST(ec); + } { boost::dll::fs::error_code ec; shared_library sl(shared_library_path, ec);