• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 // Defines base::PathProviderPosix, default path provider on POSIX OSes that
6 // don't have their own base_paths_OS.cc implementation (i.e. all but Mac and
7 // Android).
8 
9 #include <ostream>
10 #include <string>
11 
12 #include "base/base_paths.h"
13 #include "base/environment.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/logging.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/nix/xdg_util.h"
19 #include "base/path_service.h"
20 #include "base/process/process_metrics.h"
21 #include "build/build_config.h"
22 
23 #if defined(OS_FREEBSD)
24 #include <sys/param.h>
25 #include <sys/sysctl.h>
26 #elif defined(OS_SOLARIS)
27 #include <stdlib.h>
28 #endif
29 
30 namespace base {
31 
PathProviderPosix(int key,FilePath * result)32 bool PathProviderPosix(int key, FilePath* result) {
33   FilePath path;
34   switch (key) {
35     case base::FILE_EXE:
36     case base::FILE_MODULE: {  // TODO(evanm): is this correct?
37 #if defined(OS_LINUX)
38       FilePath bin_dir;
39       if (!ReadSymbolicLink(FilePath(kProcSelfExe), &bin_dir)) {
40         NOTREACHED() << "Unable to resolve " << kProcSelfExe << ".";
41         return false;
42       }
43       *result = bin_dir;
44       return true;
45 #elif defined(OS_FREEBSD)
46       int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
47       char bin_dir[PATH_MAX + 1];
48       size_t length = sizeof(bin_dir);
49       // Upon return, |length| is the number of bytes written to |bin_dir|
50       // including the string terminator.
51       int error = sysctl(name, 4, bin_dir, &length, NULL, 0);
52       if (error < 0 || length <= 1) {
53         NOTREACHED() << "Unable to resolve path.";
54         return false;
55       }
56       *result = FilePath(FilePath::StringType(bin_dir, length - 1));
57       return true;
58 #elif defined(OS_SOLARIS)
59       char bin_dir[PATH_MAX + 1];
60       if (realpath(getexecname(), bin_dir) == NULL) {
61         NOTREACHED() << "Unable to resolve " << getexecname() << ".";
62         return false;
63       }
64       *result = FilePath(bin_dir);
65       return true;
66 #elif defined(OS_OPENBSD)
67       // There is currently no way to get the executable path on OpenBSD
68       char* cpath;
69       if ((cpath = getenv("CHROME_EXE_PATH")) != NULL)
70         *result = FilePath(cpath);
71       else
72         *result = FilePath("/usr/local/chrome/chrome");
73       return true;
74 #endif
75     }
76     case base::DIR_SOURCE_ROOT: {
77       // Allow passing this in the environment, for more flexibility in build
78       // tree configurations (sub-project builds, gyp --output_dir, etc.)
79       scoped_ptr<base::Environment> env(base::Environment::Create());
80       std::string cr_source_root;
81       if (env->GetVar("CR_SOURCE_ROOT", &cr_source_root)) {
82         path = FilePath(cr_source_root);
83         if (base::PathExists(path)) {
84           *result = path;
85           return true;
86         } else {
87           DLOG(WARNING) << "CR_SOURCE_ROOT is set, but it appears to not "
88                         << "point to a directory.";
89         }
90       }
91       // On POSIX, unit tests execute two levels deep from the source root.
92       // For example:  out/{Debug|Release}/net_unittest
93       if (PathService::Get(base::DIR_EXE, &path)) {
94         *result = path.DirName().DirName();
95         return true;
96       }
97 
98       DLOG(ERROR) << "Couldn't find your source root.  "
99                   << "Try running from your chromium/src directory.";
100       return false;
101     }
102     case base::DIR_USER_DESKTOP:
103       *result = base::nix::GetXDGUserDirectory("DESKTOP", "Desktop");
104       return true;
105     case base::DIR_CACHE: {
106       scoped_ptr<base::Environment> env(base::Environment::Create());
107       FilePath cache_dir(base::nix::GetXDGDirectory(env.get(), "XDG_CACHE_HOME",
108                                                     ".cache"));
109       *result = cache_dir;
110       return true;
111     }
112   }
113   return false;
114 }
115 
116 }  // namespace base
117