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.
5 // This is really Posix minus Mac. Mac code is in base_paths_mac.mm.
7 #include "base/base_paths.h"
10 #if defined(OS_FREEBSD)
11 #include <sys/param.h>
12 #include <sys/sysctl.h>
15 #include "base/environment.h"
16 #include "base/file_path.h"
17 #include "base/file_util.h"
18 #include "base/logging.h"
19 #include "base/path_service.h"
20 #include "base/scoped_ptr.h"
21 #include "base/sys_string_conversions.h"
22 #include "base/xdg_util.h"
27 const char kSelfExe
[] = "/proc/self/exe";
28 #elif defined(OS_SOLARIS)
29 const char kSelfExe
[] = getexecname();
32 bool PathProviderPosix(int key
, FilePath
* result
) {
36 case base::FILE_MODULE
: { // TODO(evanm): is this correct?
38 char bin_dir
[PATH_MAX
+ 1];
39 int bin_dir_size
= readlink(kSelfExe
, bin_dir
, PATH_MAX
);
40 if (bin_dir_size
< 0 || bin_dir_size
> PATH_MAX
) {
41 NOTREACHED() << "Unable to resolve " << kSelfExe
<< ".";
44 bin_dir
[bin_dir_size
] = 0;
45 *result
= FilePath(bin_dir
);
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.";
56 bin_dir
[strlen(bin_dir
)] = 0;
57 *result
= FilePath(bin_dir
);
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("base/base_paths_posix.cc"))) {
72 LOG(WARNING
) << "CR_SOURCE_ROOT is set, but it appears to not "
73 << "point to the correct source root directory.";
76 // On POSIX, unit tests execute two levels deep from the source root.
77 // For example: sconsbuild/{Debug|Release}/net_unittest
78 if (PathService::Get(base::DIR_EXE
, &path
)) {
79 path
= path
.DirName().DirName();
80 if (file_util::PathExists(path
.Append("base/base_paths_posix.cc"))) {
85 // In a case of WebKit-only checkout, executable files are put into
86 // WebKit/out/{Debug|Release}, and we should return WebKit/WebKit/chromium
87 // for DIR_SOURCE_ROOT.
88 if (PathService::Get(base::DIR_EXE
, &path
)) {
89 path
= path
.DirName().DirName().Append("WebKit/chromium");
90 if (file_util::PathExists(path
.Append("base/base_paths_posix.cc"))) {
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("base/base_paths_posix.cc"))) {
102 LOG(ERROR
) << "Couldn't find your source root. "
103 << "Try running from your chromium/src directory.";
106 case base::DIR_USER_CACHE
:
107 scoped_ptr
<base::Environment
> env(base::Environment::Create());
108 FilePath
cache_dir(base::GetXDGDirectory(env
.get(), "XDG_CACHE_HOME",