blob: 84120097d6f1f4668fbfd3d386a4b271f31474c2 [file] [log] [blame]
[email protected]9bc8cff2010-04-03 01:05:391// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]b2e97292008-09-02 18:20:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]9e9b6e8e2009-12-02 08:45:015// This is really Posix minus Mac. Mac code is in base_paths_mac.mm.
6
[email protected]5d1937bb2009-11-21 01:29:007#include "base/base_paths.h"
[email protected]b2e97292008-09-02 18:20:348
9#include <unistd.h>
[email protected]99aae102010-05-10 16:30:2710#if defined(OS_FREEBSD)
11#include <sys/param.h>
12#include <sys/sysctl.h>
13#endif
[email protected]b2e97292008-09-02 18:20:3414
[email protected]76b90d312010-08-03 03:00:5015#include "base/environment.h"
[email protected]640517f2008-10-30 23:54:0416#include "base/file_path.h"
[email protected]b2e97292008-09-02 18:20:3417#include "base/file_util.h"
18#include "base/logging.h"
19#include "base/path_service.h"
[email protected]9e9b6e8e2009-12-02 08:45:0120#include "base/scoped_ptr.h"
[email protected]b2e97292008-09-02 18:20:3421#include "base/sys_string_conversions.h"
[email protected]1c657852010-04-22 23:28:0522#include "base/xdg_util.h"
[email protected]b2e97292008-09-02 18:20:3423
24namespace base {
25
[email protected]4a34ce02009-08-31 22:25:0026#if defined(OS_LINUX)
27const char kSelfExe[] = "/proc/self/exe";
[email protected]a1208912010-02-17 14:15:0828#elif defined(OS_SOLARIS)
29const char kSelfExe[] = getexecname();
[email protected]4a34ce02009-08-31 22:25:0030#endif
31
[email protected]5d1937bb2009-11-21 01:29:0032bool PathProviderPosix(int key, FilePath* result) {
[email protected]640517f2008-10-30 23:54:0433 FilePath path;
[email protected]b2e97292008-09-02 18:20:3434 switch (key) {
35 case base::FILE_EXE:
[email protected]4a34ce02009-08-31 22:25:0036 case base::FILE_MODULE: { // TODO(evanm): is this correct?
[email protected]99aae102010-05-10 16:30:2737#if defined(OS_LINUX)
[email protected]b2e97292008-09-02 18:20:3438 char bin_dir[PATH_MAX + 1];
[email protected]4a34ce02009-08-31 22:25:0039 int bin_dir_size = readlink(kSelfExe, bin_dir, PATH_MAX);
[email protected]b2e97292008-09-02 18:20:3440 if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) {
[email protected]4a34ce02009-08-31 22:25:0041 NOTREACHED() << "Unable to resolve " << kSelfExe << ".";
[email protected]b2e97292008-09-02 18:20:3442 return false;
43 }
44 bin_dir[bin_dir_size] = 0;
[email protected]4792a262008-11-19 16:50:0345 *result = FilePath(bin_dir);
[email protected]b2e97292008-09-02 18:20:3446 return true;
[email protected]99aae102010-05-10 16:30:2747#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
[email protected]b2e97292008-09-02 18:20:3460 }
[email protected]632be2f2010-04-21 23:28:4361 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.)
[email protected]76b90d312010-08-03 03:00:5064 scoped_ptr<base::Environment> env(base::Environment::Create());
[email protected]632be2f2010-04-21 23:28:4365 std::string cr_source_root;
66 if (env->GetEnv("CR_SOURCE_ROOT", &cr_source_root)) {
67 path = FilePath(cr_source_root);
68 if (file_util::PathExists(path.Append("base/base_paths_posix.cc"))) {
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 }
[email protected]5d1937bb2009-11-21 01:29:0076 // On POSIX, unit tests execute two levels deep from the source root.
[email protected]04a40f842009-04-01 20:13:0477 // For example: sconsbuild/{Debug|Release}/net_unittest
[email protected]95d050e2009-09-10 19:30:4678 if (PathService::Get(base::DIR_EXE, &path)) {
79 path = path.DirName().DirName();
[email protected]5d1937bb2009-11-21 01:29:0080 if (file_util::PathExists(path.Append("base/base_paths_posix.cc"))) {
[email protected]95d050e2009-09-10 19:30:4681 *result = path;
82 return true;
83 }
84 }
[email protected]14a25e502010-06-15 06:53:5285 // 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"))) {
91 *result = path;
92 return true;
93 }
94 }
[email protected]95d050e2009-09-10 19:30:4695 // 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) &&
[email protected]5d1937bb2009-11-21 01:29:0098 file_util::PathExists(path.Append("base/base_paths_posix.cc"))) {
[email protected]95d050e2009-09-10 19:30:4699 *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;
[email protected]632be2f2010-04-21 23:28:43105 }
[email protected]9e9b6e8e2009-12-02 08:45:01106 case base::DIR_USER_CACHE:
[email protected]76b90d312010-08-03 03:00:50107 scoped_ptr<base::Environment> env(base::Environment::Create());
[email protected]9e9b6e8e2009-12-02 08:45:01108 FilePath cache_dir(base::GetXDGDirectory(env.get(), "XDG_CACHE_HOME",
109 ".cache"));
110 *result = cache_dir;
111 return true;
[email protected]b2e97292008-09-02 18:20:34112 }
113 return false;
114}
115
116} // namespace base