diff options
author | Piotr Jaroszyński | 2010-04-08 01:40:31 +0200 |
---|---|---|
committer | Michael Brown | 2010-08-19 13:31:13 +0200 |
commit | 18d3c12b01466e424d9a54e4dbbba94e7859ec48 (patch) | |
tree | 1e55385d625f14d5cf34c64af6cee0b09efc2957 /src/interface/linux | |
parent | [linux] Add most of the linux api (diff) | |
download | ipxe-18d3c12b01466e424d9a54e4dbbba94e7859ec48.tar.gz ipxe-18d3c12b01466e424d9a54e4dbbba94e7859ec48.tar.xz ipxe-18d3c12b01466e424d9a54e4dbbba94e7859ec48.zip |
[linux] Add console
Add linux console using stdin/out. Configure the attached terminal for
readline use.
Signed-off-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface/linux')
-rw-r--r-- | src/interface/linux/linux_console.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/interface/linux/linux_console.c b/src/interface/linux/linux_console.c new file mode 100644 index 00000000..0fdb8f2f --- /dev/null +++ b/src/interface/linux/linux_console.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +FILE_LICENCE(GPL2_OR_LATER); + +/** @file + * + * Linux console implementation. + * + */ + +#include <console.h> + +#include <ipxe/init.h> +#include <ipxe/keys.h> +#include <linux_api.h> + +#include <linux/termios.h> +#include <asm/errno.h> + +static void linux_console_putchar(int c) +{ + /* write to stdout */ + if (linux_write(1, &c, 1) != 1) + DBG("linux_console write failed (%s)\n", linux_strerror(linux_errno)); +} + +static int linux_console_getchar() +{ + char c; + + /* read from stdin */ + if (linux_read(0, &c, 1) < 0) { + DBG("linux_console read failed (%s)\n", linux_strerror(linux_errno)); + return 0; + } + /* backspace seems to be returned as ascii del, map it here */ + if (c == 0x7f) + return KEY_BACKSPACE; + else + return c; +} + +static int linux_console_iskey() +{ + struct pollfd pfd; + pfd.fd = 0; + pfd.events = POLLIN; + + /* poll for data to be read on stdin */ + if (linux_poll(&pfd, 1, 0) == -1) { + DBG("linux_console poll failed (%s)\n", linux_strerror(linux_errno)); + return 0; + } + + if (pfd.revents & POLLIN) + return 1; + else + return 0; +} + +struct console_driver linux_console __console_driver = { + .disabled = 0, + .putchar = linux_console_putchar, + .getchar = linux_console_getchar, + .iskey = linux_console_iskey, +}; + +static int linux_tcgetattr(int fd, struct termios *termios_p) +{ + return linux_ioctl(fd, TCGETS, termios_p); +} + +static int linux_tcsetattr(int fd, int optional_actions, const struct termios *termios_p) +{ + unsigned long int cmd; + + switch (optional_actions) + { + case TCSANOW: + cmd = TCSETS; + break; + case TCSADRAIN: + cmd = TCSETSW; + break; + case TCSAFLUSH: + cmd = TCSETSF; + break; + default: + linux_errno = EINVAL; + return -1; + } + + return linux_ioctl(fd, cmd, termios_p); +} + +/** Saved termios attributes */ +static struct termios saved_termios; + +/** Setup the terminal for our use */ +static void linux_console_startup(void) +{ + struct termios t; + + if (linux_tcgetattr(0, &t)) { + DBG("linux_console tcgetattr failed (%s)", linux_strerror(linux_errno)); + return; + } + + saved_termios = t; + + /* Disable canonical mode and echo. Let readline handle that */ + t.c_lflag &= ~(ECHO | ICANON); + /* stop ^C from sending a signal */ + t.c_cc[VINTR] = 0; + + if (linux_tcsetattr(0, TCSAFLUSH, &t)) + DBG("linux_console tcsetattr failed (%s)", linux_strerror(linux_errno)); +} + +/** Restores original terminal attributes on shutdown */ +static void linux_console_shutdown(int flags __unused) +{ + if (linux_tcsetattr(0, TCSAFLUSH, &saved_termios)) + DBG("linux_console tcsetattr failed (%s)", linux_strerror(linux_errno)); +} + +struct startup_fn linux_console_startup_fn __startup_fn(STARTUP_EARLY) = { + .startup = linux_console_startup, + .shutdown = linux_console_shutdown, +}; |