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