15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defines base::PathProviderPosix, default path provider on POSIX OSes that 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// don't have their own base_paths_OS.cc implementation (i.e. all but Mac and 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Android). 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ostream> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_paths.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/nix/xdg_util.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 2058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process_metrics.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_FREEBSD) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/param.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/sysctl.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_SOLARIS) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PathProviderPosix(int key, FilePath* result) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath path; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (key) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case base::FILE_EXE: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case base::FILE_MODULE: { // TODO(evanm): is this correct? 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath bin_dir; 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ReadSymbolicLink(FilePath(kProcSelfExe), &bin_dir)) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to resolve " << kProcSelfExe << "."; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = bin_dir; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_FREEBSD) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char bin_dir[PATH_MAX + 1]; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t length = sizeof(bin_dir); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Upon return, |length| is the number of bytes written to |bin_dir| 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // including the string terminator. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error = sysctl(name, 4, bin_dir, &length, NULL, 0); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error < 0 || length <= 1) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to resolve path."; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = FilePath(FilePath::StringType(bin_dir, length - 1)); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_SOLARIS) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char bin_dir[PATH_MAX + 1]; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (realpath(getexecname(), bin_dir) == NULL) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to resolve " << getexecname() << "."; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = FilePath(bin_dir); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_OPENBSD) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is currently no way to get the executable path on OpenBSD 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* cpath; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((cpath = getenv("CHROME_EXE_PATH")) != NULL) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = FilePath(cpath); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = FilePath("/usr/local/chrome/chrome"); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case base::DIR_SOURCE_ROOT: { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow passing this in the environment, for more flexibility in build 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tree configurations (sub-project builds, gyp --output_dir, etc.) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string cr_source_root; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env->GetVar("CR_SOURCE_ROOT", &cr_source_root)) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = FilePath(cr_source_root); 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (base::PathExists(path)) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = path; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "CR_SOURCE_ROOT is set, but it appears to not " 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "point to a directory."; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On POSIX, unit tests execute two levels deep from the source root. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For example: out/{Debug|Release}/net_unittest 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PathService::Get(base::DIR_EXE, &path)) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = path.DirName().DirName(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Couldn't find your source root. " 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Try running from your chromium/src directory."; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case base::DIR_USER_DESKTOP: 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = base::nix::GetXDGUserDirectory("DESKTOP", "Desktop"); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case base::DIR_CACHE: { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath cache_dir(base::nix::GetXDGDirectory(env.get(), "XDG_CACHE_HOME", 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".cache")); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = cache_dir; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 117