blob: 7ae9024a2765ddb013c4c2edb3fd22bd3835560d [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "util/exe_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "util/build_config.h"
#if defined(OS_MACOSX)
#include <mach-o/dyld.h>
#elif defined(OS_WIN)
#include <windows.h>
#include "base/win/win_util.h"
#elif defined(OS_FREEBSD) || defined(OS_NETBSD)
#include <limits.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#elif defined(OS_HAIKU)
#include <OS.h>
#include <image.h>
#elif defined(OS_SOLARIS)
#include <stdlib.h>
#endif
#if defined(OS_MACOSX)
base::FilePath GetExePath() {
// Executable path can have relative references ("..") depending on
// how the app was launched.
uint32_t executable_length = 0;
_NSGetExecutablePath(NULL, &executable_length);
DCHECK_GT(executable_length, 1u);
std::string executable_path;
int rv = _NSGetExecutablePath(
base::WriteInto(&executable_path, executable_length), &executable_length);
DCHECK_EQ(rv, 0);
// _NSGetExecutablePath may return paths containing ./ or ../ which makes
// FilePath::DirName() work incorrectly, convert it to absolute path so that
// paths such as DIR_SOURCE_ROOT can work, since we expect absolute paths to
// be returned here.
return base::MakeAbsoluteFilePath(base::FilePath(executable_path));
}
#elif defined(OS_WIN)
base::FilePath GetExePath() {
char16_t system_buffer[MAX_PATH];
system_buffer[0] = 0;
if (GetModuleFileName(NULL, base::ToWCharT(system_buffer), MAX_PATH) == 0) {
return base::FilePath();
}
return base::FilePath(system_buffer);
}
#elif defined(OS_FREEBSD)
base::FilePath GetExePath() {
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
char buf[PATH_MAX];
size_t buf_size = PATH_MAX;
if (sysctl(mib, 4, buf, &buf_size, nullptr, 0) == -1) {
return base::FilePath();
}
return base::FilePath(buf);
}
#elif defined(OS_NETBSD)
base::FilePath GetExePath() {
int mib[] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_PATHNAME};
char buf[PATH_MAX];
size_t buf_size = PATH_MAX;
if (sysctl(mib, 4, buf, &buf_size, nullptr, 0) == -1) {
return base::FilePath();
}
return base::FilePath(buf);
}
#elif defined(OS_HAIKU)
base::FilePath GetExePath() {
image_info i_info;
int32 image_cookie = 0;
while (get_next_image_info(B_CURRENT_TEAM, &image_cookie, &i_info) == B_OK) {
if (i_info.type == B_APP_IMAGE) {
break;
}
}
return base::FilePath(std::string(i_info.name));
}
#elif defined(OS_SOLARIS)
base::FilePath GetExePath() {
const char *raw = getexecname();
if (raw == NULL) {
return base::FilePath();
}
return base::FilePath(raw);
}
#elif defined(OS_ZOS)
base::FilePath GetExePath() {
char path[PATH_MAX];
if (__getexepath(path, sizeof(path), getpid()) != 0) {
return base::FilePath();
}
return base::FilePath(path);
}
#else
base::FilePath GetExePath() {
base::FilePath result;
const char kProcSelfExe[] = "/proc/self/exe";
if (!ReadSymbolicLink(base::FilePath(kProcSelfExe), &result)) {
NOTREACHED() << "Unable to resolve " << kProcSelfExe << ".";
return base::FilePath();
}
return result;
}
#endif