| // 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_CMD_CONSOLE_H_ | |
| #define SRC_DEVELOPER_CMD_CONSOLE_H_ | |
| #include <fuchsia/hardware/pty/c/fidl.h> | |
| #include <lib/async/dispatcher.h> | |
| #include <lib/fdio/unsafe.h> | |
| #include <string> | |
| #include <vector> | |
| #include "src/developer/cmd/autocomplete.h" | |
| #include "src/developer/cmd/command.h" | |
| #include "src/lib/fsl/tasks/fd_waiter.h" | |
| #include "src/lib/line_input/modal_line_input.h" | |
| namespace cmd { | |
| class Console { | |
| public: | |
| class Client { | |
| public: | |
| // A |command| has been read from the console. | |
| // | |
| // Must 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. | |
| virtual zx_status_t OnConsoleCommand(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; | |
| // The user is asking for autocomplete suggestions. | |
| // | |
| // The client is expected to provide zero or more completions synchronously | |
| // during this method. The given |autocomplete| is valid only for the | |
| // duration of this method. | |
| virtual void OnConsoleAutocomplete(Autocomplete* autocomplete) = 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|. | |
| Console(Client* client, async_dispatcher_t* dispatcher, int input_fd); | |
| ~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(); | |
| 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::ModalLineInputStdout line_input_; | |
| bool should_read_ = false; | |
| }; | |
| } // namespace cmd | |
| #endif // SRC_DEVELOPER_CMD_CONSOLE_H_ |