| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_DEVELOPER_SHELL_CONSOLE_CONSOLE_H_ |
| #define SRC_DEVELOPER_SHELL_CONSOLE_CONSOLE_H_ |
| |
| #include <lib/async/dispatcher.h> |
| #include <lib/fdio/unsafe.h> |
| |
| #include <iostream> |
| #include <string> |
| #include <vector> |
| |
| #include "src/developer/shell/console/command.h" |
| #include "src/lib/fsl/tasks/fd_waiter.h" |
| #include "src/lib/line_input/modal_line_input.h" |
| |
| namespace shell::console { |
| |
| class Console { |
| public: |
| class Client { |
| public: |
| Client() = default; |
| |
| // A |command| has been read from the console. |
| // |
| // May return ZX_ERR_STOP, ZX_ERR_NEXT, or ZX_ERR_ASYNC. |
| // |
| // If this function returns |ZX_ERR_STOP|, no further commands will be read |
| // from the console. |
| // |
| // If this function returns |ZX_ERR_NEXT|, the console will continue to read |
| // commands from the console. |
| // |
| // If this function returns |ZX_ERR_ASYNC|, the console will wait to read |
| // further commands from the console until the |GetNextCommand| method is |
| // called on the console. |
| // |
| // If this function returns anything else, the result will be treated as a |
| // ZX_ERR_NEXT, but the resulting error message will be printed to the |
| // console. |
| virtual Err OnConsoleCommand(std::unique_ptr<Command> command) = 0; |
| |
| // The console has been asked to interrupt the current command. |
| // |
| // Called only between |OnConsoleCommand| returning |ZX_ERR_ASYNC| and |
| // |GetNextCommand|. |
| virtual void OnConsoleInterrupt() = 0; |
| |
| // The console has encountered an error. |
| // |
| // No further commands can be read from the console. |
| // |
| // If the console reaches the end of the input stream, |status| will be |
| // |ZX_ERR_PEER_CLOSED|. |
| virtual void OnConsoleError(zx_status_t status) = 0; |
| |
| protected: |
| virtual ~Client(); |
| }; |
| |
| // Create an interactive console. |
| // |
| // Reads input from the |input_fd| file description, which is typically |
| // |STDIN_FILENO| but can be set to another valid file descriptor for testing. |
| // |
| // Uses |dispatcher| to schedule asynchronous waits on |input_fd|. |
| // Writes to stdout and stderr. |
| Console(Client* client, async_dispatcher_t* dispatcher, int input_fd, |
| std::ostream& out = std::cout, std::ostream& err = std::cerr); |
| ~Console(); |
| |
| // Initialize the console. |
| // |
| // The given |prompt| is displayed to the user when the user is expected to |
| // input another command. |
| // |
| // Does not prompt the user to input a command. Call |GetNextCommand| to get |
| // the first command from the user. |
| void Init(std::string prompt); |
| |
| // Get the next command from the user. |
| // |
| // This operation completes asynchronously by calling methods on the |client| |
| // provided to the constructor. A single call to |GetNextCommand| will result |
| // in one or more calls to |OnConsoleCommand| and at most one call to |
| // |OnConsoleError|. See |Client| for more information. |
| // |
| // It is an error to call |GetNextCommand| again until |OnConsoleCommand| has |
| // returned |ZX_ERR_ASYNC|. |
| void GetNextCommand(); |
| |
| // Output the given string |output| to this console's standard output stream. |
| std::ostream& out() { return out_stream_; } |
| |
| // Output the given string |output| to this console's standard error stream. |
| std::ostream& err() { return err_stream_; } |
| |
| private: |
| void WaitForInputAsynchronously(); |
| void WaitForInterruptAsynchronously(); |
| void OnAccept(const std::string& line); |
| void OnError(zx_status_t status); |
| |
| Client* client_; |
| int input_fd_; |
| fsl::FDWaiter input_waiter_; |
| |
| fdio_t* tty_ = nullptr; |
| fsl::FDWaiter interrupt_waiter_; |
| |
| line_input::ModalLineInput line_input_; |
| |
| bool should_read_ = false; |
| |
| std::ostream& out_stream_; |
| std::ostream& err_stream_; |
| }; |
| |
| } // namespace shell::console |
| |
| #endif // SRC_DEVELOPER_SHELL_CONSOLE_CONSOLE_H_ |