diff options
author | Malfurious <m@lfurio.us> | 2023-07-02 08:18:23 -0400 |
---|---|---|
committer | Malfurious <m@lfurio.us> | 2023-07-02 08:18:23 -0400 |
commit | cb6993e4d31086411c1dd147ec820d37cbc2d01c (patch) | |
tree | 982f43703fac39ca75d0daeb35cb2e9c6f5d3ee6 /console.c | |
parent | 7e89874f23e0423a4c9476cba8b566809685cfb9 (diff) | |
download | misplays-cb6993e4d31086411c1dd147ec820d37cbc2d01c.tar.gz misplays-cb6993e4d31086411c1dd147ec820d37cbc2d01c.zip |
Add basic pty console
This is good enough for early testing of the debugger functionality, but
should be improved in the future.
Signed-off-by: Malfurious <m@lfurio.us>
Diffstat (limited to 'console.c')
-rw-r--r-- | console.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/console.c b/console.c new file mode 100644 index 0000000..f8949d7 --- /dev/null +++ b/console.c @@ -0,0 +1,100 @@ +#include <fcntl.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#include "console.h" +#include "curshelpers.h" + +int console_init(struct console *cons) { + int master = open("/dev/ptmx", O_RDWR | O_NOCTTY); + if (master < 0) { + return -1; + } + + if (grantpt(master) || unlockpt(master)) { + close(master); + return -1; + } + + int flags = fcntl(master, F_GETFL, 0); + if (flags < 0) { + close(master); + return -1; + } + + flags |= O_NONBLOCK; + if (fcntl(master, F_SETFL, flags) < 0) { + close(master); + return -1; + } + + cons->master = master; + cons->isesc = 0; + return 0; +} + +int console_deinit(struct console *cons) { + close(cons->master); + return 0; +} + +void console_enter(struct console *cons, PANEL *pan) { + (void)cons; + keypad(stdscr, FALSE); + curs_set(TRUE); + raw(); + top_panel(pan); +} + +void console_leave(struct console *cons, PANEL *pan) { + (void)cons; + (void)pan; + keypad(stdscr, TRUE); + curs_set(FALSE); + cbreak(); +} + +void console_update(struct console *cons, PANEL *pan) { + ssize_t nb; + char c; + + while ((nb = read(cons->master, &c, 1)) > 0) { + if (!cons->isesc) { + if (c == 0x1b) { + cons->isesc = 1; + } else if (c != 0x0d) { + pprintw(pan, "%c", c); + } + } else { + if (c == 'm') { + cons->isesc = 0; + } + } + } +} + +void console_input(struct console *cons, int ch) { + write(cons->master, &ch, 1); +} + +int console_configslave(struct console *cons) { + if (setsid() < 0) { + return -1; + } + + int slave = open(ptsname(cons->master), O_RDWR); + if (slave < 0) { + return -1; + } + + if (ioctl(slave, TIOCSCTTY, 0) < 0) { + close(slave); + return -1; + } + + dup2(slave, STDIN_FILENO); + dup2(slave, STDOUT_FILENO); + dup2(slave, STDERR_FILENO); + return slave; +} |