|
|
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.