base_paths_linux.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2010 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 "base/base_paths.h" 6 7#include <unistd.h> 8#if defined(OS_FREEBSD) 9#include <sys/param.h> 10#include <sys/sysctl.h> 11#endif 12 13#include "base/environment.h" 14#include "base/file_path.h" 15#include "base/file_util.h" 16#include "base/logging.h" 17#include "base/path_service.h" 18#include "base/scoped_ptr.h" 19#include "base/sys_string_conversions.h" 20#include "base/nix/xdg_util.h" 21 22namespace base { 23 24#if defined(OS_LINUX) 25const char kSelfExe[] = "/proc/self/exe"; 26#elif defined(OS_SOLARIS) 27const char kSelfExe[] = getexecname(); 28#endif 29 30// The name of this file relative to the source root. This is used for checking 31// that the source checkout is in the correct place. 32static const char kThisSourceFile[] = "base/base_paths_linux.cc"; 33 34bool PathProviderPosix(int key, FilePath* result) { 35 FilePath path; 36 switch (key) { 37 case base::FILE_EXE: 38 case base::FILE_MODULE: { // TODO(evanm): is this correct? 39#if defined(OS_LINUX) 40 FilePath bin_dir; 41 if (!file_util::ReadSymbolicLink(FilePath(kSelfExe), &bin_dir)) { 42 NOTREACHED() << "Unable to resolve " << kSelfExe << "."; 43 return false; 44 } 45 *result = bin_dir; 46 return true; 47#elif defined(OS_FREEBSD) 48 int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; 49 char bin_dir[PATH_MAX + 1]; 50 size_t length = sizeof(bin_dir); 51 int error = sysctl(name, 4, bin_dir, &length, NULL, 0); 52 if (error < 0 || length == 0 || strlen(bin_dir) == 0) { 53 NOTREACHED() << "Unable to resolve path."; 54 return false; 55 } 56 bin_dir[strlen(bin_dir)] = 0; 57 *result = FilePath(bin_dir); 58 return true; 59#endif 60 } 61 case base::DIR_SOURCE_ROOT: { 62 // Allow passing this in the environment, for more flexibility in build 63 // tree configurations (sub-project builds, gyp --output_dir, etc.) 64 scoped_ptr<base::Environment> env(base::Environment::Create()); 65 std::string cr_source_root; 66 if (env->GetVar("CR_SOURCE_ROOT", &cr_source_root)) { 67 path = FilePath(cr_source_root); 68 if (file_util::PathExists(path.Append(kThisSourceFile))) { 69 *result = path; 70 return true; 71 } else { 72 LOG(WARNING) << "CR_SOURCE_ROOT is set, but it appears to not " 73 << "point to the correct source root directory."; 74 } 75 } 76 // On POSIX, unit tests execute two levels deep from the source root. 77 // For example: out/{Debug|Release}/net_unittest 78 if (PathService::Get(base::DIR_EXE, &path)) { 79 path = path.DirName().DirName(); 80 if (file_util::PathExists(path.Append(kThisSourceFile))) { 81 *result = path; 82 return true; 83 } 84 } 85 // In a case of WebKit-only checkout, executable files are put into 86 // <root of checkout>/out/{Debug|Release}, and we should return 87 // <root of checkout>/Source/WebKit/chromium for DIR_SOURCE_ROOT. 88 if (PathService::Get(base::DIR_EXE, &path)) { 89 path = path.DirName().DirName().Append("Source/WebKit/chromium"); 90 if (file_util::PathExists(path.Append(kThisSourceFile))) { 91 *result = path; 92 return true; 93 } 94 } 95 // If that failed (maybe the build output is symlinked to a different 96 // drive) try assuming the current directory is the source root. 97 if (file_util::GetCurrentDirectory(&path) && 98 file_util::PathExists(path.Append(kThisSourceFile))) { 99 *result = path; 100 return true; 101 } 102 LOG(ERROR) << "Couldn't find your source root. " 103 << "Try running from your chromium/src directory."; 104 return false; 105 } 106 case base::DIR_CACHE: 107#ifdef ANDROID 108 NOTREACHED(); 109 return false; 110#else 111 scoped_ptr<base::Environment> env(base::Environment::Create()); 112 FilePath cache_dir(base::nix::GetXDGDirectory(env.get(), "XDG_CACHE_HOME", 113 ".cache")); 114 *result = cache_dir; 115 return true; 116#endif 117 } 118 return false; 119} 120 121} // namespace base 122