program_location_impl.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
  2. // Copyright 2015-2019 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. #ifndef BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP
  8. #define BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP
  9. #include <boost/dll/config.hpp>
  10. #include <boost/dll/detail/system_error.hpp>
  11. #include <boost/predef/os.h>
  12. #ifdef BOOST_HAS_PRAGMA_ONCE
  13. # pragma once
  14. #endif
  15. #if BOOST_OS_MACOS || BOOST_OS_IOS
  16. #include <mach-o/dyld.h>
  17. namespace boost { namespace dll { namespace detail {
  18. inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
  19. ec.clear();
  20. char path[1024];
  21. uint32_t size = sizeof(path);
  22. if (_NSGetExecutablePath(path, &size) == 0)
  23. return boost::dll::fs::path(path);
  24. char *p = new char[size];
  25. if (_NSGetExecutablePath(p, &size) != 0) {
  26. ec = boost::dll::fs::make_error_code(
  27. boost::dll::fs::errc::bad_file_descriptor
  28. );
  29. }
  30. boost::dll::fs::path ret(p);
  31. delete[] p;
  32. return ret;
  33. }
  34. }}} // namespace boost::dll::detail
  35. #elif BOOST_OS_SOLARIS
  36. #include <stdlib.h>
  37. namespace boost { namespace dll { namespace detail {
  38. inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
  39. ec.clear();
  40. return boost::dll::fs::path(getexecname());
  41. }
  42. }}} // namespace boost::dll::detail
  43. #elif BOOST_OS_BSD_FREE
  44. #include <sys/types.h>
  45. #include <sys/sysctl.h>
  46. #include <stdlib.h>
  47. namespace boost { namespace dll { namespace detail {
  48. inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code& ec) {
  49. ec.clear();
  50. int mib[4];
  51. mib[0] = CTL_KERN;
  52. mib[1] = KERN_PROC;
  53. mib[2] = KERN_PROC_PATHNAME;
  54. mib[3] = -1;
  55. char buf[10240];
  56. size_t cb = sizeof(buf);
  57. sysctl(mib, 4, buf, &cb, NULL, 0);
  58. return boost::dll::fs::path(buf);
  59. }
  60. }}} // namespace boost::dll::detail
  61. #elif BOOST_OS_BSD_NET
  62. namespace boost { namespace dll { namespace detail {
  63. inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
  64. return boost::dll::fs::read_symlink("/proc/curproc/exe", ec);
  65. }
  66. }}} // namespace boost::dll::detail
  67. #elif BOOST_OS_BSD_DRAGONFLY
  68. namespace boost { namespace dll { namespace detail {
  69. inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
  70. return boost::dll::fs::read_symlink("/proc/curproc/file", ec);
  71. }
  72. }}} // namespace boost::dll::detail
  73. #elif BOOST_OS_QNX
  74. #include <fstream>
  75. #include <string> // for std::getline
  76. namespace boost { namespace dll { namespace detail {
  77. inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
  78. ec.clear();
  79. std::string s;
  80. std::ifstream ifs("/proc/self/exefile");
  81. std::getline(ifs, s);
  82. if (ifs.fail() || s.empty()) {
  83. ec = boost::dll::fs::make_error_code(
  84. boost::dll::fs::errc::bad_file_descriptor
  85. );
  86. }
  87. return boost::dll::fs::path(s);
  88. }
  89. }}} // namespace boost::dll::detail
  90. #else // BOOST_OS_LINUX || BOOST_OS_UNIX || BOOST_OS_HPUX || BOOST_OS_ANDROID
  91. namespace boost { namespace dll { namespace detail {
  92. inline boost::dll::fs::path program_location_impl(boost::dll::fs::error_code &ec) {
  93. // We can not use
  94. // boost::dll::detail::path_from_handle(dlopen(NULL, RTLD_LAZY | RTLD_LOCAL), ignore);
  95. // because such code returns empty path.
  96. return boost::dll::fs::read_symlink("/proc/self/exe", ec); // Linux specific
  97. }
  98. }}} // namespace boost::dll::detail
  99. #endif
  100. #endif // BOOST_DLL_DETAIL_POSIX_PROGRAM_LOCATION_IMPL_HPP