| 205 | } |
| 206 | |
| 207 | BAN::ErrorOr<void> Execute::execute_command(const PipedCommand& piped_command) |
| 208 | { |
| 209 | ASSERT(!piped_command.commands.empty()); |
| 210 | |
| 211 | int last_pipe_rd = STDIN_FILENO; |
| 212 | |
| 213 | BAN::Vector<pid_t> child_pids; |
| 214 | TRY(child_pids.resize(piped_command.commands.size(), 0)); |
| 215 | |
| 216 | BAN::Vector<int> child_codes; |
| 217 | TRY(child_codes.resize(piped_command.commands.size(), 126)); |
| 218 | |
| 219 | const auto evaluate_arguments = |
| 220 | [this](BAN::Span<const CommandArgument> arguments) -> BAN::ErrorOr<BAN::Vector<BAN::String>> |
| 221 | { |
| 222 | BAN::Vector<BAN::String> result; |
| 223 | TRY(result.reserve(arguments.size())); |
| 224 | for (const auto& argument : arguments) |
| 225 | TRY(result.push_back(TRY(argument.evaluate(*this)))); |
| 226 | return result; |
| 227 | }; |
| 228 | |
| 229 | const auto evaluate_environment = |
| 230 | [this](BAN::Span<const SingleCommand::EnvironmentVariable> environments) -> BAN::ErrorOr<BAN::Vector<InternalCommand::Environment>> |
| 231 | { |
| 232 | BAN::Vector<InternalCommand::Environment> result; |
| 233 | TRY(result.reserve(environments.size())); |
| 234 | for (const auto& environment : environments) |
| 235 | TRY(result.emplace_back(environment.name, TRY(environment.value.evaluate(*this)))); |
| 236 | return result; |
| 237 | }; |
| 238 | |
| 239 | const auto evaluate_redirections = |
| 240 | [this](BAN::Span<const SingleCommand::Redirection> redirections) -> BAN::ErrorOr<BAN::Vector<InternalCommand::Redirection>> |
| 241 | { |
| 242 | BAN::Vector<InternalCommand::Redirection> result; |
| 243 | TRY(result.reserve(redirections.size())); |
| 244 | for (const auto& redirection : redirections) |
| 245 | TRY(result.push_back({ |
| 246 | .path = TRY(redirection.destination.evaluate(*this)), |
| 247 | .source_fd = redirection.source_fd, |
| 248 | .append = redirection.append, |
| 249 | .duplicate = redirection.duplicate, |
| 250 | .input = redirection.input, |
| 251 | })); |
| 252 | return result; |
| 253 | }; |
| 254 | |
| 255 | const int stdin_flags = fcntl(STDIN_FILENO, F_GETFL); |
| 256 | if (stdin_flags == -1) |
| 257 | perror("fcntl"); |
| 258 | |
| 259 | for (size_t i = 0; i < piped_command.commands.size(); i++) |
| 260 | { |
| 261 | int new_pipe[2] { STDIN_FILENO, STDOUT_FILENO }; |
| 262 | if (i != piped_command.commands.size() - 1) |
| 263 | if (pipe(new_pipe) == -1) |
| 264 | return BAN::Error::from_errno(errno); |
no test coverage detected