diff options
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; +} |