base_paths_linux.cc revision 201ade2fbba22bfb27ae029f4d23fca6ded109a0
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 char bin_dir[PATH_MAX + 1]; 41 int bin_dir_size = readlink(kSelfExe, bin_dir, PATH_MAX); 42 if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) { 43 NOTREACHED() << "Unable to resolve " << kSelfExe << "."; 44 return false; 45 } 46 bin_dir[bin_dir_size] = 0; 47 *result = FilePath(bin_dir); 48 return true; 49#elif defined(OS_FREEBSD) 50 int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; 51 char bin_dir[PATH_MAX + 1]; 52 size_t length = sizeof(bin_dir); 53 int error = sysctl(name, 4, bin_dir, &length, NULL, 0); 54 if (error < 0 || length == 0 || strlen(bin_dir) == 0) { 55 NOTREACHED() << "Unable to resolve path."; 56 return false; 57 } 58 bin_dir[strlen(bin_dir)] = 0; 59 *result = FilePath(bin_dir); 60 return true; 61#endif 62 } 63 case base::DIR_SOURCE_ROOT: { 64 // Allow passing this in the environment, for more flexibility in build 65 // tree configurations (sub-project builds, gyp --output_dir, etc.) 66 scoped_ptr<base::Environment> env(base::Environment::Create()); 67 std::string cr_source_root; 68 if (env->GetVar("CR_SOURCE_ROOT", &cr_source_root)) { 69 path = FilePath(cr_source_root); 70 if (file_util::PathExists(path.Append(kThisSourceFile))) { 71 *result = path; 72 return true; 73 } else { 74 LOG(WARNING) << "CR_SOURCE_ROOT is set, but it appears to not " 75 << "point to the correct source root directory."; 76 } 77 } 78 // On POSIX, unit tests execute two levels deep from the source root. 79 // For example: sconsbuild/{Debug|Release}/net_unittest 80 if (PathService::Get(base::DIR_EXE, &path)) { 81 path = path.DirName().DirName(); 82 if (file_util::PathExists(path.Append(kThisSourceFile))) { 83 *result = path; 84 return true; 85 } 86 } 87 // In a case of WebKit-only checkout, executable files are put into 88 // WebKit/out/{Debug|Release}, and we should return WebKit/WebKit/chromium 89 // for DIR_SOURCE_ROOT. 90 if (PathService::Get(base::DIR_EXE, &path)) { 91 path = path.DirName().DirName().Append("WebKit/chromium"); 92 if (file_util::PathExists(path.Append(kThisSourceFile))) { 93 *result = path; 94 return true; 95 } 96 } 97 // If that failed (maybe the build output is symlinked to a different 98 // drive) try assuming the current directory is the source root. 99 if (file_util::GetCurrentDirectory(&path) && 100 file_util::PathExists(path.Append(kThisSourceFile))) { 101 *result = path; 102 return true; 103 } 104 LOG(ERROR) << "Couldn't find your source root. " 105 << "Try running from your chromium/src directory."; 106 return false; 107 } 108<<<<<<< HEAD 109 case base::DIR_USER_CACHE: 110#ifdef ANDROID 111 NOTREACHED(); 112 return false; 113#else 114======= 115 case base::DIR_CACHE: 116>>>>>>> Chromium.org at 9.0.597.55 117 scoped_ptr<base::Environment> env(base::Environment::Create()); 118 FilePath cache_dir(base::nix::GetXDGDirectory(env.get(), "XDG_CACHE_HOME", 119 ".cache")); 120 *result = cache_dir; 121 return true; 122#endif 123 } 124 return false; 125} 126 127} // namespace base 128