1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "util/exe_path.h"
6
7 #include "base/files/file_util.h"
8 #include "base/logging.h"
9 #include "base/strings/string_util.h"
10 #include "util/build_config.h"
11
12 #if defined(OS_MACOSX)
13 #include <mach-o/dyld.h>
14 #elif defined(OS_WIN)
15 #include <windows.h>
16
17 #include "base/win/win_util.h"
18 #elif defined(OS_FREEBSD)
19 #include <limits.h>
20 #include <sys/sysctl.h>
21 #include <sys/types.h>
22 #elif defined(OS_HAIKU)
23 #include <OS.h>
24 #include <image.h>
25 #endif
26
27 #if defined(OS_MACOSX)
28
GetExePath()29 base::FilePath GetExePath() {
30 // Executable path can have relative references ("..") depending on
31 // how the app was launched.
32 uint32_t executable_length = 0;
33 _NSGetExecutablePath(NULL, &executable_length);
34 DCHECK_GT(executable_length, 1u);
35 std::string executable_path;
36 int rv = _NSGetExecutablePath(
37 base::WriteInto(&executable_path, executable_length), &executable_length);
38 DCHECK_EQ(rv, 0);
39
40 // _NSGetExecutablePath may return paths containing ./ or ../ which makes
41 // FilePath::DirName() work incorrectly, convert it to absolute path so that
42 // paths such as DIR_SOURCE_ROOT can work, since we expect absolute paths to
43 // be returned here.
44 return base::MakeAbsoluteFilePath(base::FilePath(executable_path));
45 }
46
47 #elif defined(OS_WIN)
48
GetExePath()49 base::FilePath GetExePath() {
50 char16_t system_buffer[MAX_PATH];
51 system_buffer[0] = 0;
52 if (GetModuleFileName(NULL, base::ToWCharT(system_buffer), MAX_PATH) == 0) {
53 return base::FilePath();
54 }
55 return base::FilePath(system_buffer);
56 }
57
58 #elif defined(OS_FREEBSD)
59
GetExePath()60 base::FilePath GetExePath() {
61 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
62 char buf[PATH_MAX];
63 size_t buf_size = PATH_MAX;
64 if (sysctl(mib, 4, buf, &buf_size, nullptr, 0) == -1) {
65 return base::FilePath();
66 }
67 return base::FilePath(buf);
68 }
69
70 #elif defined(OS_HAIKU)
71
GetExePath()72 base::FilePath GetExePath() {
73 image_info i_info;
74 int32 image_cookie = 0;
75 while (get_next_image_info(B_CURRENT_TEAM, &image_cookie, &i_info) == B_OK) {
76 if (i_info.type == B_APP_IMAGE) {
77 break;
78 }
79 }
80 return base::FilePath(std::string(i_info.name));
81 }
82
83 #else
84
GetExePath()85 base::FilePath GetExePath() {
86 base::FilePath result;
87 const char kProcSelfExe[] = "/proc/self/exe";
88 if (!ReadSymbolicLink(base::FilePath(kProcSelfExe), &result)) {
89 NOTREACHED() << "Unable to resolve " << kProcSelfExe << ".";
90 return base::FilePath();
91 }
92 return result;
93 }
94
95 #endif
96