terom@92: #ifndef CONSOLE_H terom@92: #define CONSOLE_H terom@92: terom@92: /** terom@92: * @file terom@92: * terom@92: * An interactive line-based console interface for runtime configuration. terom@92: * terom@92: * This uses the GNU readline library to implement the console, and hence, the console uses global state, and there terom@92: * can only be one console per process - not that it should matter, since the console requires a tty. terom@92: * terom@92: * XXX: the log module interferes with this terom@92: */ terom@92: #include "error.h" terom@92: #include terom@92: #include terom@92: terom@92: /** terom@92: * Callbacks for event-based actions terom@92: */ terom@92: struct console_callbacks { terom@93: /** terom@93: * A line was read from the console. terom@93: */ terom@93: void (*on_line) (const char *line, void *arg); terom@170: terom@170: /** terom@170: * EOF was read on the console. terom@170: * terom@170: * Note that for interactive consoles, EOF isn't actually EOF - there might be multiple EOFs... terom@170: */ terom@170: void (*on_eof) (void *arg); terom@92: }; terom@92: terom@92: /** terom@92: * Configuration info for console operation terom@92: */ terom@92: struct console_config { terom@92: /** The prompt to use when displaying lines */ terom@92: const char *prompt; terom@92: }; terom@92: terom@92: /** terom@93: * The console state. terom@93: * terom@93: * You may replace the callbacks/cb_arg field with a new one at any time, using console_set_callbacks(). terom@92: */ terom@92: struct console { terom@170: /** Configuration */ terom@170: struct console_config config; terom@170: terom@170: /** Input event */ terom@92: struct event *ev; terom@92: terom@170: /** Callback functions */ terom@92: const struct console_callbacks *callbacks; terom@92: terom@170: /** Callback context argument */ terom@92: void *cb_arg; terom@92: terom@92: /** Already initialized? */ terom@92: bool initialized; terom@137: terom@137: /** Set as log output function? */ terom@137: bool log_output; terom@137: terom@137: /** In the middle of input? */ terom@137: bool have_input; terom@92: }; terom@92: terom@92: /** terom@93: * Initialize the console, setting up the TTY and input handler. terom@93: * terom@93: * @param console_ptr returned new console struct terom@93: * @param ev_base the libevent base to use terom@93: * @param config configuration things for the console terom@93: * @param callbacks optional callbacks, can be updated later terom@93: * @param cb_arg option callback argument, can be updated later terom@93: * @param err returned error info terom@92: */ terom@92: err_t console_init (struct console **console_ptr, struct event_base *ev_base, const struct console_config *config, terom@92: const struct console_callbacks *callbacks, void *cb_arg, struct error_info *err); terom@92: terom@92: /** terom@93: * Replace the current callbacks with the given new ones. terom@93: */ terom@93: void console_set_callbacks (struct console *console, const struct console_callbacks *callbacks, void *cb_arg); terom@93: terom@93: /** terom@137: * Output a full line (without included newline) on the console, trying not to interfere with the input too much. terom@137: */ terom@137: err_t console_print (struct console *console, const char *line); terom@137: terom@137: /** terom@137: * Install this console as the log output handler terom@137: */ terom@137: void console_set_log_output (struct console *console); terom@137: terom@137: /** terom@92: * Deinitialize the console, restoring the TTY and releasing resources terom@92: */ terom@92: void console_destroy (struct console *console); terom@92: terom@92: #endif /* CONSOLE_H */