blob: ab3b257b022b52fcc4404fa73849631365d18c8a [file] [log] [blame]
// 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_