1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "common/libs/utils/environment.h"
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <iostream>
22
23 namespace cuttlefish {
24
StringFromEnv(const std::string & varname,const std::string & defval)25 std::string StringFromEnv(const std::string& varname,
26 const std::string& defval) {
27 const char* const valstr = getenv(varname.c_str());
28 if (!valstr) {
29 return defval;
30 }
31 return valstr;
32 }
33
34 /**
35 * at runtime, return the arch of the host: e.g. aarch64, x86_64, etc
36 *
37 * uses "`which uname` -m"
38 *
39 * @return arch string on success, "" on failure
40 */
HostArch()41 std::string HostArch() {
42 static std::string arch;
43 static bool cached = false;
44
45 if (cached) {
46 return arch;
47 }
48 cached = true;
49
50 // good to check if uname exists and is executable
51 // or, guarantee uname is availabe by dependency list
52 FILE* pip = popen("uname -m", "r");
53 if (!pip) {
54 return std::string{};
55 }
56
57 auto read_from_file =
58 [](FILE* fp, size_t len) {
59 /*
60 * to see if input is longer than len,
61 * we read up to len+1. If the length is len+1,
62 * then the input is too long
63 */
64 decltype(len) upper = len + 1;
65 std::string format("%");
66 format.append(std::to_string(upper)).append("s");
67 std::shared_ptr<char> buf(new char[upper],
68 std::default_delete<char[]>());
69 if (fscanf(fp, format.c_str(), buf.get()) == EOF) {
70 return std::string{};
71 }
72 std::string result(buf.get());
73 return (result.length() < upper) ? result : std::string{};
74 };
75 arch = read_from_file(pip, 20);
76 pclose(pip);
77
78 // l and r trim on arch
79 static const char* whitespace = "\t\n\r\f\v ";
80 arch.erase(arch.find_last_not_of(whitespace) + 1); // r trim
81 arch.erase(0, arch.find_first_not_of(whitespace)); // l trim
82 return arch;
83 }
84
85 } // namespace cuttlefish
86