1 /* 2 * Copyright (C) 2016 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 #ifndef ANDROID_OS_DUMPSTATE_UTIL_H_ 17 #define ANDROID_OS_DUMPSTATE_UTIL_H_ 18 19 #include <cstdint> 20 #include <string> 21 22 namespace android { 23 namespace os { 24 namespace dumpstate { 25 26 /* 27 * Defines the Linux account that should be executing a command. 28 */ 29 enum PrivilegeMode { 30 /* Explicitly change the `uid` and `gid` to be `shell`.*/ 31 DROP_ROOT, 32 /* Don't change the `uid` and `gid`. */ 33 DONT_DROP_ROOT, 34 /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */ 35 SU_ROOT 36 }; 37 38 /* 39 * Defines what should happen with the main output stream (`stdout` or fd) of a command. 40 */ 41 enum OutputMode { 42 /* Don't change main output. */ 43 NORMAL_OUTPUT, 44 /* Redirect main output to `stderr`. */ 45 REDIRECT_TO_STDERR 46 }; 47 48 /* 49 * Value object used to set command options. 50 * 51 * Typically constructed using a builder with chained setters. Examples: 52 * 53 * CommandOptions::WithTimeout(20).AsRoot().Build(); 54 * CommandOptions::WithTimeout(10).Always().RedirectStderr().Build(); 55 * 56 * Although the builder could be used to dynamically set values. Example: 57 * 58 * CommandOptions::CommandOptionsBuilder options = 59 * CommandOptions::WithTimeout(10); 60 * if (!is_user_build()) { 61 * options.AsRoot(); 62 * } 63 * RunCommand("command", {"args"}, options.Build()); 64 */ 65 class CommandOptions { 66 private: 67 class CommandOptionsValues { 68 private: 69 CommandOptionsValues(int64_t timeout); 70 71 int64_t timeout_; 72 bool always_; 73 PrivilegeMode account_mode_; 74 OutputMode output_mode_; 75 std::string logging_message_; 76 77 friend class CommandOptions; 78 friend class CommandOptionsBuilder; 79 }; 80 81 CommandOptions(const CommandOptionsValues& values); 82 83 const CommandOptionsValues values; 84 85 public: 86 class CommandOptionsBuilder { 87 public: 88 /* Sets the command to always run, even on `dry-run` mode. */ 89 CommandOptionsBuilder& Always(); 90 /* Sets the command's PrivilegeMode as `SU_ROOT` */ 91 CommandOptionsBuilder& AsRoot(); 92 /* Sets the command's PrivilegeMode as `DROP_ROOT` */ 93 CommandOptionsBuilder& DropRoot(); 94 /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */ 95 CommandOptionsBuilder& RedirectStderr(); 96 /* When not empty, logs a message before executing the command. 97 * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */ 98 CommandOptionsBuilder& Log(const std::string& message); 99 /* Builds the command options. */ 100 CommandOptions Build(); 101 102 private: 103 CommandOptionsBuilder(int64_t timeout); 104 CommandOptionsValues values; 105 friend class CommandOptions; 106 }; 107 108 /** Gets the command timeout, in seconds. */ 109 int64_t Timeout() const; 110 /* Checks whether the command should always be run, even on dry-run mode. */ 111 bool Always() const; 112 /** Gets the PrivilegeMode of the command. */ 113 PrivilegeMode PrivilegeMode() const; 114 /** Gets the OutputMode of the command. */ 115 OutputMode OutputMode() const; 116 /** Gets the logging message header, it any. */ 117 std::string LoggingMessage() const; 118 119 /** Creates a builder with the requied timeout. */ 120 static CommandOptionsBuilder WithTimeout(int64_t timeout); 121 122 // Common options. 123 static CommandOptions DEFAULT; 124 static CommandOptions AS_ROOT; 125 }; 126 127 /* 128 * System properties helper. 129 */ 130 class PropertiesHelper { 131 friend class DumpstateBaseTest; 132 133 public: 134 /* 135 * Gets whether device is running a `user` build. 136 */ 137 static bool IsUserBuild(); 138 139 /* 140 * When running in dry-run mode, skips the real dumps and just print the section headers. 141 * 142 * Useful when debugging dumpstate or other bugreport-related activities. 143 * 144 * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true. 145 */ 146 static bool IsDryRun(); 147 148 private: 149 static std::string build_type_; 150 static int dry_run_; 151 }; 152 153 /* 154 * Forks a command, waits for it to finish, and returns its status. 155 * 156 * |fd| file descriptor that receives the command's 'stdout'. 157 * |title| description of the command printed on `stdout` (or empty to skip 158 * description). 159 * |full_command| array containing the command (first entry) and its arguments. 160 * Must contain at least one element. 161 * |options| optional argument defining the command's behavior. 162 */ 163 int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command, 164 const CommandOptions& options = CommandOptions::DEFAULT); 165 166 /* 167 * Dumps the contents of a file into a file descriptor. 168 * 169 * |fd| file descriptor where the file is dumped into. 170 * |title| description of the command printed on `stdout` (or empty to skip 171 * description). 172 * |path| location of the file to be dumped. 173 */ 174 int DumpFileToFd(int fd, const std::string& title, const std::string& path); 175 176 /* 177 * Finds the process id by process name. 178 * |ps_name| the process name we want to search for 179 */ 180 int GetPidByName(const std::string& ps_name); 181 182 } // namespace dumpstate 183 } // namespace os 184 } // namespace android 185 186 #endif // ANDROID_OS_DUMPSTATE_UTIL_H_ 187