| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "common/libs/utils/environment.h" |
| #include "common/libs/utils/files.h" |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <iostream> |
| |
| #include <android-base/logging.h> |
| |
| namespace cuttlefish { |
| |
| std::string StringFromEnv(const std::string& varname, |
| const std::string& defval) { |
| const char* const valstr = getenv(varname.c_str()); |
| if (!valstr) { |
| return defval; |
| } |
| return valstr; |
| } |
| |
| /** |
| * at runtime, return the arch of the host: e.g. aarch64, x86_64, etc |
| * |
| * uses "`which uname` -m" |
| * |
| * @return arch string on success, "" on failure |
| */ |
| std::string HostArchStr() { |
| static std::string arch; |
| static bool cached = false; |
| |
| if (cached) { |
| return arch; |
| } |
| cached = true; |
| |
| // good to check if uname exists and is executable |
| // or, guarantee uname is available by dependency list |
| FILE* pip = popen("uname -m", "r"); |
| if (!pip) { |
| return std::string{}; |
| } |
| |
| auto read_from_file = |
| [](FILE* fp, size_t len) { |
| /* |
| * to see if input is longer than len, |
| * we read up to len+1. If the length is len+1, |
| * then the input is too long |
| */ |
| decltype(len) upper = len + 1; |
| std::string format("%"); |
| format.append(std::to_string(upper)).append("s"); |
| std::shared_ptr<char> buf(new char[upper], |
| std::default_delete<char[]>()); |
| if (fscanf(fp, format.c_str(), buf.get()) == EOF) { |
| return std::string{}; |
| } |
| std::string result(buf.get()); |
| return (result.length() < upper) ? result : std::string{}; |
| }; |
| arch = read_from_file(pip, 20); |
| pclose(pip); |
| |
| // l and r trim on arch |
| static const char* whitespace = "\t\n\r\f\v "; |
| arch.erase(arch.find_last_not_of(whitespace) + 1); // r trim |
| arch.erase(0, arch.find_first_not_of(whitespace)); // l trim |
| return arch; |
| } |
| |
| Arch HostArch() { |
| std::string arch_str = HostArchStr(); |
| if (arch_str == "aarch64") { |
| return Arch::Arm64; |
| } else if (arch_str == "arm") { |
| return Arch::Arm; |
| } else if (arch_str == "x86_64") { |
| return Arch::X86_64; |
| } else if (arch_str.size() == 4 && arch_str[0] == 'i' && arch_str[2] == '8' && |
| arch_str[3] == '6') { |
| return Arch::X86; |
| } else { |
| LOG(FATAL) << "Unknown host architecture: " << arch_str; |
| return Arch::X86; |
| } |
| } |
| |
| bool IsHostCompatible(Arch arch) { |
| Arch host_arch = HostArch(); |
| return arch == host_arch || (arch == Arch::Arm && host_arch == Arch::Arm64) || |
| (arch == Arch::X86 && host_arch == Arch::X86_64); |
| } |
| |
| static bool IsRunningInDocker() { |
| // if /.dockerenv exists, it's inside a docker container |
| static std::string docker_env_path("/.dockerenv"); |
| static bool ret = |
| FileExists(docker_env_path) || DirectoryExists(docker_env_path); |
| return ret; |
| } |
| |
| bool IsRunningInContainer() { |
| // TODO: add more if we support other containers than docker |
| return IsRunningInDocker(); |
| } |
| |
| } // namespace cuttlefish |