|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2010 Piotr JaroszyĆski <[email protected]> ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of the ! 7: * License, or any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program; if not, write to the Free Software ! 16: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ! 17: */ ! 18: ! 19: FILE_LICENCE(GPL2_OR_LATER); ! 20: ! 21: /** @file ! 22: * ! 23: * Linux console implementation. ! 24: * ! 25: */ ! 26: ! 27: #include <ipxe/console.h> ! 28: ! 29: #include <ipxe/init.h> ! 30: #include <ipxe/keys.h> ! 31: #include <linux_api.h> ! 32: ! 33: #include <linux/termios.h> ! 34: #include <asm/errno.h> ! 35: ! 36: static void linux_console_putchar(int c) ! 37: { ! 38: /* write to stdout */ ! 39: if (linux_write(1, &c, 1) != 1) ! 40: DBG("linux_console write failed (%s)\n", linux_strerror(linux_errno)); ! 41: } ! 42: ! 43: static int linux_console_getchar() ! 44: { ! 45: char c; ! 46: ! 47: /* read from stdin */ ! 48: if (linux_read(0, &c, 1) < 0) { ! 49: DBG("linux_console read failed (%s)\n", linux_strerror(linux_errno)); ! 50: return 0; ! 51: } ! 52: /* backspace seems to be returned as ascii del, map it here */ ! 53: if (c == 0x7f) ! 54: return KEY_BACKSPACE; ! 55: else ! 56: return c; ! 57: } ! 58: ! 59: static int linux_console_iskey() ! 60: { ! 61: struct pollfd pfd; ! 62: pfd.fd = 0; ! 63: pfd.events = POLLIN; ! 64: ! 65: /* poll for data to be read on stdin */ ! 66: if (linux_poll(&pfd, 1, 0) == -1) { ! 67: DBG("linux_console poll failed (%s)\n", linux_strerror(linux_errno)); ! 68: return 0; ! 69: } ! 70: ! 71: if (pfd.revents & POLLIN) ! 72: return 1; ! 73: else ! 74: return 0; ! 75: } ! 76: ! 77: struct console_driver linux_console __console_driver = { ! 78: .disabled = 0, ! 79: .putchar = linux_console_putchar, ! 80: .getchar = linux_console_getchar, ! 81: .iskey = linux_console_iskey, ! 82: }; ! 83: ! 84: static int linux_tcgetattr(int fd, struct termios *termios_p) ! 85: { ! 86: return linux_ioctl(fd, TCGETS, termios_p); ! 87: } ! 88: ! 89: static int linux_tcsetattr(int fd, int optional_actions, const struct termios *termios_p) ! 90: { ! 91: unsigned long int cmd; ! 92: ! 93: switch (optional_actions) ! 94: { ! 95: case TCSANOW: ! 96: cmd = TCSETS; ! 97: break; ! 98: case TCSADRAIN: ! 99: cmd = TCSETSW; ! 100: break; ! 101: case TCSAFLUSH: ! 102: cmd = TCSETSF; ! 103: break; ! 104: default: ! 105: linux_errno = EINVAL; ! 106: return -1; ! 107: } ! 108: ! 109: return linux_ioctl(fd, cmd, termios_p); ! 110: } ! 111: ! 112: /** Saved termios attributes */ ! 113: static struct termios saved_termios; ! 114: ! 115: /** Setup the terminal for our use */ ! 116: static void linux_console_startup(void) ! 117: { ! 118: struct termios t; ! 119: ! 120: if (linux_tcgetattr(0, &t)) { ! 121: DBG("linux_console tcgetattr failed (%s)", linux_strerror(linux_errno)); ! 122: return; ! 123: } ! 124: ! 125: saved_termios = t; ! 126: ! 127: /* Disable canonical mode and echo. Let readline handle that */ ! 128: t.c_lflag &= ~(ECHO | ICANON); ! 129: /* stop ^C from sending a signal */ ! 130: t.c_cc[VINTR] = 0; ! 131: ! 132: if (linux_tcsetattr(0, TCSAFLUSH, &t)) ! 133: DBG("linux_console tcsetattr failed (%s)", linux_strerror(linux_errno)); ! 134: } ! 135: ! 136: /** Restores original terminal attributes on shutdown */ ! 137: static void linux_console_shutdown(int flags __unused) ! 138: { ! 139: if (linux_tcsetattr(0, TCSAFLUSH, &saved_termios)) ! 140: DBG("linux_console tcsetattr failed (%s)", linux_strerror(linux_errno)); ! 141: } ! 142: ! 143: struct startup_fn linux_console_startup_fn __startup_fn(STARTUP_EARLY) = { ! 144: .startup = linux_console_startup, ! 145: .shutdown = linux_console_shutdown, ! 146: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.