base_paths_posix.cc 3.8 KB

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