From 254a63ca90b60efb8c5324d9740c52b34b27f8fc Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 10 Oct 2016 16:23:07 +1100 Subject: [PATCH] exe: split into platform units --- Makefile.am | 6 +-- exe.cpp | 116 ------------------------------------------------ exe_freebsd.cpp | 25 +++++++++++ exe_linux.cpp | 51 +++++++++++++++++++++ exe_win32.cpp | 21 +++++++++ test/exe.cpp | 13 +++--- 6 files changed, 108 insertions(+), 124 deletions(-) delete mode 100644 exe.cpp create mode 100644 exe_freebsd.cpp create mode 100644 exe_linux.cpp create mode 100644 exe_win32.cpp diff --git a/Makefile.am b/Makefile.am index fce8e76f..855d5ef5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -71,7 +71,6 @@ UTIL_FILES = \ endian.hpp \ except.cpp \ except.hpp \ - exe.cpp \ exe.hpp \ extent.cpp \ extent.hpp \ @@ -298,16 +297,17 @@ POSIX_FILES = \ if PLATFORM_LINUX -UTIL_FILES += $(POSIX_FILES) +UTIL_FILES += $(POSIX_FILES) exe_linux.cpp endif if PLATFORM_FREEBSD -UTIL_FILES += $(POSIX_FILES) +UTIL_FILES += $(POSIX_FILES) exe_freebsd.cpp endif if PLATFORM_WIN32 UTIL_FILES += \ debug_win32.cpp \ + exe_win32.cpp \ io_win32.cpp \ io_win32.hpp \ io_win32.ipp \ diff --git a/exe.cpp b/exe.cpp deleted file mode 100644 index 30740a98..00000000 --- a/exe.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright 2010-2012 Danny Robson - */ - - -#include "exe.hpp" - -#include "platform.hpp" - -#if defined(PLATFORM_LINUX) - -#include "except.hpp" -#include "cast.hpp" - -#include -#include -#include -#include -#include -#include - -std::experimental::filesystem::path -util::image_path (void) { - static const char PROC_SELF[] = "/proc/self/exe"; - - // We can't use lstat to check the size of the link in proc, as Linux - // will return 0 for most entries under proc. Instead we've got to - // iterate for a correct size. - std::vector resolved (256); - -retry: - const auto written = readlink (PROC_SELF, resolved.data (), resolved.size ()); - if (written < 0) - errno_error::throw_code (); - - if (sign_cast (written) == resolved.size ()) { - resolved.resize (resolved.size () * 2); - goto retry; - } - - return std::experimental::filesystem::path (resolved.data (), resolved.data () + written); -} - -#elif defined(PLATFORM_FREEBSD) - -#include "types.hpp" -#include "except.hpp" - -#include -#include - -std::experimental::filesystem::path -util::image_path (void) -{ - int name[] = { - CTL_KERN, - KERN_PROC, - KERN_PROC_PATHNAME, - -1 - }; - - char data[1024]; - size_t len = sizeof (data); - - auto err = sysctl (name, elems (name), data, &len, nullptr, 0); - errno_error::try_code (err); - - return std::experimental::filesystem::path (std::cbegin (data), std::cbegin (data) + len); -} - -#elif defined(PLATFORM_WIN32) - -#include "except.hpp" - -#include - -std::experimental::filesystem::path -util::image_path (void) { - std::vector resolved (256); - -retry: - const auto written = GetModuleFileName (nullptr, resolved.data (), resolved.size ()); - if (written == 0) - win32_error::throw_code (); - - if (written == resolved.size ()) { - resolved.resize (resolved.size () * 2); - goto retry; - } - - return std::experimental::filesystem::path (resolved.data (), resolved.data () + written); -} - -#else - #error "Unknown platform" - -// Mac OS X: _NSGetExecutablePath() (man 3 dyld) -// Linux: readlink /proc/self/exe -// Solaris: getexecname() -// FreeBSD: sysctl CTL_KERN KERN_PROC KERN_PROC_PATHNAME -1 -// BSD with procfs: readlink /proc/curproc/file -// Windows: GetModuleFileName() with hModule = NULL - -#endif diff --git a/exe_freebsd.cpp b/exe_freebsd.cpp new file mode 100644 index 00000000..e705fe88 --- /dev/null +++ b/exe_freebsd.cpp @@ -0,0 +1,25 @@ + +#include "types.hpp" +#include "except.hpp" + +#include +#include + +std::experimental::filesystem::path +util::image_path (void) +{ + int name[] = { + CTL_KERN, + KERN_PROC, + KERN_PROC_PATHNAME, + -1 + }; + + char data[1024]; + size_t len = sizeof (data); + + auto err = sysctl (name, elems (name), data, &len, nullptr, 0); + errno_error::try_code (err); + + return std::experimental::filesystem::path (std::cbegin (data), std::cbegin (data) + len); +} diff --git a/exe_linux.cpp b/exe_linux.cpp new file mode 100644 index 00000000..a7f02317 --- /dev/null +++ b/exe_linux.cpp @@ -0,0 +1,51 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2010-2016 Danny Robson + */ + +#include "./exe.hpp" + +#include "./except.hpp" +#include "./cast.hpp" + +#include +#include + +#include + + +/////////////////////////////////////////////////////////////////////////////// +std::experimental::filesystem::path +util::image_path (void) +{ + static const char PROC_SELF[] = "/proc/self/exe"; + + // We can't use lstat to check the size of the link in proc, as Linux + // will return 0 for most entries under proc. Instead we've got to + // iterate for a correct size. + std::vector resolved (256); + +retry: + const auto written = readlink (PROC_SELF, resolved.data (), resolved.size ()); + if (written < 0) + errno_error::throw_code (); + + if (sign_cast (written) == resolved.size ()) { + resolved.resize (resolved.size () * 2); + goto retry; + } + + return std::experimental::filesystem::path (resolved.data (), resolved.data () + written); +} + diff --git a/exe_win32.cpp b/exe_win32.cpp new file mode 100644 index 00000000..d5dbb9a2 --- /dev/null +++ b/exe_win32.cpp @@ -0,0 +1,21 @@ + +#include "except.hpp" + +#include + +std::experimental::filesystem::path +util::image_path (void) { + std::vector resolved (256); + +retry: + const auto written = GetModuleFileName (nullptr, resolved.data (), resolved.size ()); + if (written == 0) + win32_error::throw_code (); + + if (written == resolved.size ()) { + resolved.resize (resolved.size () * 2); + goto retry; + } + + return std::experimental::filesystem::path (resolved.data (), resolved.data () + written); +} diff --git a/test/exe.cpp b/test/exe.cpp index 025aab76..efa78aab 100644 --- a/test/exe.cpp +++ b/test/exe.cpp @@ -1,12 +1,15 @@ -#include "./exe.hpp" #include "./tap.hpp" +#include "./exe.hpp" + #include + +/////////////////////////////////////////////////////////////////////////////// int -main (void) +main (int, char**) { - util::TAP::logger tap; - tap.expect_eq (util::image_path ().stem (), "exe", "identify executable path"); - return tap.status (); + util::TAP::logger tap; + tap.expect_eq (util::image_path ().stem (), "exe", "identify executable path"); + return tap.status (); }