1 // Copyright 2014 Renato Tegon Forti, Antony Polukhin. 2 // Copyright 2015 Antony Polukhin. 3 // 4 // Distributed under the Boost Software License, Version 1.0. 5 // (See accompanying file LICENSE_1_0.txt 6 // or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #ifndef BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP 9 #define BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP 10 11 #include <boost/config.hpp> 12 #include <boost/dll/detail/system_error.hpp> 13 #include <boost/filesystem/path.hpp> 14 #include <boost/predef/os.h> 15 16 #ifdef BOOST_HAS_PRAGMA_ONCE 17 # pragma once 18 #endif 19 20 #if BOOST_OS_MACOS || BOOST_OS_IOS 21 22 #include <mach-o/dyld.h> 23 24 namespace boost { namespace dll { namespace detail { program_location_impl(boost::system::error_code & ec)25 inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { 26 ec.clear(); 27 28 char path[1024]; 29 uint32_t size = sizeof(path); 30 if (_NSGetExecutablePath(path, &size) == 0) 31 return boost::filesystem::path(path); 32 33 char *p = new char[size]; 34 if (_NSGetExecutablePath(p, &size) != 0) { 35 ec = boost::system::error_code( 36 boost::system::errc::bad_file_descriptor, 37 boost::system::generic_category() 38 ); 39 } 40 41 boost::filesystem::path ret(p); 42 delete[] p; 43 return ret; 44 } 45 }}} // namespace boost::dll::detail 46 47 #elif BOOST_OS_SOLARIS 48 49 #include <stdlib.h> 50 namespace boost { namespace dll { namespace detail { program_location_impl(boost::system::error_code & ec)51 inline boost::filesystem::path program_location_impl(boost::system::error_code& ec) { 52 ec.clear(); 53 54 return boost::filesystem::path(getexecname()); 55 } 56 }}} // namespace boost::dll::detail 57 58 #elif BOOST_OS_BSD_FREE 59 60 #include <sys/types.h> 61 #include <sys/sysctl.h> 62 #include <stdlib.h> 63 64 namespace boost { namespace dll { namespace detail { program_location_impl(boost::system::error_code & ec)65 inline boost::filesystem::path program_location_impl(boost::system::error_code& ec) { 66 ec.clear(); 67 68 int mib[4]; 69 mib[0] = CTL_KERN; 70 mib[1] = KERN_PROC; 71 mib[2] = KERN_PROC_PATHNAME; 72 mib[3] = -1; 73 char buf[10240]; 74 size_t cb = sizeof(buf); 75 sysctl(mib, 4, buf, &cb, NULL, 0); 76 77 return boost::filesystem::path(buf); 78 } 79 }}} // namespace boost::dll::detail 80 81 82 83 #elif BOOST_OS_BSD_NET 84 85 #include <boost/filesystem/operations.hpp> 86 namespace boost { namespace dll { namespace detail { program_location_impl(boost::system::error_code & ec)87 inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { 88 return boost::filesystem::read_symlink("/proc/curproc/exe", ec); 89 } 90 }}} // namespace boost::dll::detail 91 92 #elif BOOST_OS_BSD_DRAGONFLY 93 94 #include <boost/filesystem/operations.hpp> 95 namespace boost { namespace dll { namespace detail { program_location_impl(boost::system::error_code & ec)96 inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { 97 return boost::filesystem::read_symlink("/proc/curproc/file", ec); 98 } 99 }}} // namespace boost::dll::detail 100 101 #elif BOOST_OS_QNX 102 103 #include <fstream> 104 #include <string> // for std::getline 105 namespace boost { namespace dll { namespace detail { program_location_impl(boost::system::error_code & ec)106 inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { 107 ec.clear(); 108 109 std::string s; 110 std::ifstream ifs("/proc/self/exefile"); 111 std::getline(ifs, s); 112 113 if (ifs.fail() || s.empty()) { 114 ec = boost::system::error_code( 115 boost::system::errc::bad_file_descriptor, 116 boost::system::generic_category() 117 ); 118 } 119 120 return boost::filesystem::path(s); 121 } 122 }}} // namespace boost::dll::detail 123 124 #else // BOOST_OS_LINUX || BOOST_OS_UNIX || BOOST_OS_HPUX || BOOST_OS_ANDROID 125 126 #include <boost/filesystem/operations.hpp> 127 namespace boost { namespace dll { namespace detail { program_location_impl(boost::system::error_code & ec)128 inline boost::filesystem::path program_location_impl(boost::system::error_code &ec) { 129 // We can not use 130 // boost::dll::detail::path_from_handle(dlopen(NULL, RTLD_LAZY | RTLD_LOCAL), ignore); 131 // because such code returns empty path. 132 133 return boost::filesystem::read_symlink("/proc/self/exe", ec); // Linux specific 134 } 135 }}} // namespace boost::dll::detail 136 137 #endif 138 139 #endif // BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP 140 141