blob: ede23c96cd5e35f19d45611e27efce312f07a3ce [file] [log] [blame]
Felipe Lemebda15a02016-11-16 17:48:25 -08001/*
Felipe Leme6f674ae2016-11-18 17:10:33 -08002 * Copyright (C) 2016 The Android Open Source Project
Felipe Lemebda15a02016-11-16 17:48:25 -08003 *
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 FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_
17#define FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_
18
Felipe Leme6f674ae2016-11-18 17:10:33 -080019// TODO: use android::os::dumpstate (must wait until device code is refactored)
20
Felipe Lemebda15a02016-11-16 17:48:25 -080021/*
Felipe Leme46b85da2016-11-21 17:40:45 -080022 * Defines the Linux account that should be executing a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080023 */
Felipe Leme46b85da2016-11-21 17:40:45 -080024enum PrivilegeMode {
Felipe Lemebda15a02016-11-16 17:48:25 -080025 /* Explicitly change the `uid` and `gid` to be `shell`.*/
26 DROP_ROOT,
27 /* Don't change the `uid` and `gid`. */
28 DONT_DROP_ROOT,
29 /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
30 SU_ROOT
31};
32
33/*
Felipe Leme46b85da2016-11-21 17:40:45 -080034 * Defines what should happen with the main output stream (`stdout` or fd) of a command.
Felipe Lemebda15a02016-11-16 17:48:25 -080035 */
Felipe Leme46b85da2016-11-21 17:40:45 -080036enum OutputMode {
37 /* Don't change main output. */
38 NORMAL_OUTPUT,
39 /* Redirect main output to `stderr`. */
Felipe Lemebda15a02016-11-16 17:48:25 -080040 REDIRECT_TO_STDERR
41};
42
43/*
44 * Value object used to set command options.
45 *
46 * Typically constructed using a builder with chained setters. Examples:
47 *
48 * CommandOptions::WithTimeout(20).AsRoot().Build();
49 * CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
50 *
51 * Although the builder could be used to dynamically set values. Example:
52 *
53 * CommandOptions::CommandOptionsBuilder options =
54 * CommandOptions::WithTimeout(10);
55 * if (!is_user_build()) {
56 * options.AsRoot();
57 * }
58 * RunCommand("command", {"args"}, options.Build());
59 */
60class CommandOptions {
61 private:
62 class CommandOptionsValues {
63 private:
64 CommandOptionsValues(int64_t timeout);
65
66 int64_t timeout_;
67 bool always_;
Felipe Leme46b85da2016-11-21 17:40:45 -080068 PrivilegeMode account_mode_;
69 OutputMode output_mode_;
Felipe Lemebda15a02016-11-16 17:48:25 -080070 std::string logging_message_;
71
72 friend class CommandOptions;
73 friend class CommandOptionsBuilder;
74 };
75
76 CommandOptions(const CommandOptionsValues& values);
77
78 const CommandOptionsValues values;
79
80 public:
81 class CommandOptionsBuilder {
82 public:
83 /* Sets the command to always run, even on `dry-run` mode. */
84 CommandOptionsBuilder& Always();
Felipe Leme46b85da2016-11-21 17:40:45 -080085 /* Sets the command's PrivilegeMode as `SU_ROOT` */
Felipe Lemebda15a02016-11-16 17:48:25 -080086 CommandOptionsBuilder& AsRoot();
Felipe Leme46b85da2016-11-21 17:40:45 -080087 /* Sets the command's PrivilegeMode as `DROP_ROOT` */
Felipe Lemebda15a02016-11-16 17:48:25 -080088 CommandOptionsBuilder& DropRoot();
Felipe Leme46b85da2016-11-21 17:40:45 -080089 /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
Felipe Lemebda15a02016-11-16 17:48:25 -080090 CommandOptionsBuilder& RedirectStderr();
91 /* When not empty, logs a message before executing the command.
92 * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
93 CommandOptionsBuilder& Log(const std::string& message);
94 /* Builds the command options. */
95 CommandOptions Build();
96
97 private:
98 CommandOptionsBuilder(int64_t timeout);
99 CommandOptionsValues values;
100 friend class CommandOptions;
101 };
102
103 /** Gets the command timeout, in seconds. */
104 int64_t Timeout() const;
105 /* Checks whether the command should always be run, even on dry-run mode. */
106 bool Always() const;
Felipe Leme46b85da2016-11-21 17:40:45 -0800107 /** Gets the PrivilegeMode of the command. */
108 PrivilegeMode PrivilegeMode() const;
109 /** Gets the OutputMode of the command. */
110 OutputMode OutputMode() const;
Felipe Lemebda15a02016-11-16 17:48:25 -0800111 /** Gets the logging message header, it any. */
112 std::string LoggingMessage() const;
113
114 /** Creates a builder with the requied timeout. */
115 static CommandOptionsBuilder WithTimeout(int64_t timeout);
116
117 // Common options.
118 static CommandOptions DEFAULT;
119 static CommandOptions AS_ROOT_5;
120 static CommandOptions AS_ROOT_10;
121 static CommandOptions AS_ROOT_20;
122};
123
124/*
125 * Forks a command, waits for it to finish, and returns its status.
126 *
127 * |fd| file descriptor that receives the command's 'stdout'.
128 * |full_command| array containing the command (first entry) and its arguments.
Felipe Leme46b85da2016-11-21 17:40:45 -0800129 * Must contain at least one element.
Felipe Lemebda15a02016-11-16 17:48:25 -0800130 * |options| optional argument defining the command's behavior.
Felipe Lemebda15a02016-11-16 17:48:25 -0800131 */
Felipe Leme46b85da2016-11-21 17:40:45 -0800132int RunCommandToFd(int fd, const std::vector<std::string>& full_command,
133 const CommandOptions& options = CommandOptions::DEFAULT);
Felipe Lemebda15a02016-11-16 17:48:25 -0800134
135/*
136 * Dumps the contents of a file into a file descriptor.
137 *
138 * |fd| file descriptor where the file is dumped into.
139 * |path| location of the file to be dumped.
140 */
141int DumpFileToFd(int fd, const std::string& path);
142
143#endif // FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_