]>
Commit | Line | Data |
---|---|---|
6c6c850a | 1 | /** @file\r |
2 | Canonical Interactive Input Function.\r | |
3 | \r | |
4 | The functions assume that isatty() is TRUE at the time they are called.\r | |
5 | \r | |
24903bc4 | 6 | Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>\r |
6c6c850a | 7 | This program and the accompanying materials are licensed and made available\r |
8 | under the terms and conditions of the BSD License which accompanies this\r | |
9 | distribution. The full text of the license may be found at\r | |
10 | http://opensource.org/licenses/bsd-license.php.\r | |
11 | \r | |
12 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
13 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
14 | **/\r | |
15 | #include <Uefi.h>\r | |
16 | \r | |
17 | #include <LibConfig.h>\r | |
18 | \r | |
19 | #include <errno.h>\r | |
20 | #include <sys/syslimits.h>\r | |
21 | #include <sys/termios.h>\r | |
22 | #include <Device/IIO.h>\r | |
23 | #include <MainData.h>\r | |
24 | #include "IIOutilities.h"\r | |
25 | #include "IIOechoCtrl.h"\r | |
26 | \r | |
27 | /** Read a line from the input file in canonical mode.\r | |
28 | Perform echoing and input processing as directed by the termios flags.\r | |
29 | \r | |
30 | @param[in] filp A pointer to a file descriptor structure.\r | |
31 | \r | |
32 | @return The number of characters in the input buffer, or -1 if there\r | |
33 | was an error.\r | |
34 | **/\r | |
35 | ssize_t\r | |
36 | IIO_CanonRead (\r | |
37 | struct __filedes *filp\r | |
38 | )\r | |
39 | {\r | |
40 | cIIO *This;\r | |
41 | cFIFO *InBuf;\r | |
42 | struct termios *Termio;\r | |
43 | struct __filedes *fpOut;\r | |
44 | size_t NumRead;\r | |
45 | wint_t InChar;\r | |
46 | tcflag_t IFlag;\r | |
47 | tcflag_t LFlag;\r | |
48 | BOOLEAN EchoIsOK;\r | |
49 | BOOLEAN Activate;\r | |
50 | BOOLEAN FirstRead;\r | |
51 | int OutMode;\r | |
52 | UINTN MaxColumn;\r | |
53 | UINTN MaxRow;\r | |
54 | \r | |
55 | NumRead = MAX_INPUT; // Workaround "potentially uninitialized" warning\r | |
56 | EchoIsOK = FALSE;\r | |
57 | FirstRead = TRUE;\r | |
58 | This = filp->devdata;\r | |
59 | Termio = &This->Termio;\r | |
60 | InBuf = This->InBuf;\r | |
61 | \r | |
62 | // Get a copy of the flags we are going to use\r | |
63 | IFlag = Termio->c_iflag;\r | |
64 | LFlag = Termio->c_lflag;\r | |
65 | \r | |
66 | /* Determine what the current screen size is. Also validates the output device. */\r | |
67 | OutMode = IIO_GetOutputSize(STDOUT_FILENO, &MaxColumn, &MaxRow);\r | |
68 | if(OutMode >= 0) {\r | |
69 | /* Set the maximum screen dimensions. */\r | |
70 | This->MaxColumn = MaxColumn;\r | |
71 | This->MaxRow = MaxRow;\r | |
72 | \r | |
73 | /* Record where the cursor is at the beginning of this Input operation.\r | |
74 | The currently set stdout device is used to determine this. If there is\r | |
75 | no stdout, or stdout is not an interactive device, nothing is recorded.\r | |
76 | */\r | |
77 | if (IIO_GetCursorPosition(STDOUT_FILENO, &This->InitialXY.Column, &This->InitialXY.Row) >= 0) {\r | |
78 | This->CurrentXY.Column = This->InitialXY.Column;\r | |
79 | This->CurrentXY.Row = This->InitialXY.Row;\r | |
80 | EchoIsOK = TRUE; // Can only echo to stdout\r | |
81 | }\r | |
82 | }\r | |
83 | \r | |
84 | // For now, we only echo to stdout.\r | |
85 | fpOut = &gMD->fdarray[STDOUT_FILENO];\r | |
86 | \r | |
87 | // Input and process characters until BufferSize is exhausted.\r | |
88 | do {\r | |
89 | InChar = IIO_GetInChar(filp, FirstRead);\r | |
24903bc4 DM |
90 | if (InChar == WEOF) {\r |
91 | NumRead = 0;\r | |
92 | break;\r | |
93 | }\r | |
6c6c850a | 94 | FirstRead = FALSE;\r |
95 | Activate = TRUE;\r | |
96 | if(InChar == CHAR_CARRIAGE_RETURN) {\r | |
97 | if((IFlag & IGNCR) != 0) {\r | |
98 | continue; // Restart the do loop, discarding the CR\r | |
99 | }\r | |
100 | else if((IFlag & ICRNL) != 0) {\r | |
101 | InChar = L'\n';\r | |
102 | }\r | |
103 | }\r | |
104 | else if(InChar == CHAR_LINEFEED) {\r | |
105 | if((IFlag & INLCR) != 0) {\r | |
106 | InChar = L'\r';\r | |
107 | }\r | |
108 | }\r | |
109 | else if(CCEQ(Termio->c_cc[VINTR], InChar)) {\r | |
110 | if((LFlag & ISIG) != 0) {\r | |
111 | // Raise Signal\r | |
112 | // Flush Input Buffer\r | |
113 | // Return to caller\r | |
114 | InChar = IIO_ECHO_DISCARD;\r | |
115 | errno = EINTR;\r | |
116 | }\r | |
117 | else {\r | |
118 | Activate = FALSE;\r | |
119 | }\r | |
120 | }\r | |
121 | else if(CCEQ(Termio->c_cc[VQUIT], InChar)) {\r | |
122 | if((LFlag & ISIG) != 0) {\r | |
123 | // Raise Signal\r | |
124 | // Flush Input Buffer\r | |
125 | // Return to caller\r | |
126 | InChar = IIO_ECHO_DISCARD;\r | |
127 | errno = EINTR;\r | |
128 | }\r | |
129 | else {\r | |
130 | Activate = FALSE;\r | |
131 | }\r | |
132 | }\r | |
133 | else if(CCEQ(Termio->c_cc[VEOF], InChar)) {\r | |
134 | InChar = WEOF;\r | |
24903bc4 DM |
135 | NumRead = 0;\r |
136 | EchoIsOK = FALSE; // Buffer, but don't echo this character\r | |
6c6c850a | 137 | }\r |
138 | else if(CCEQ(Termio->c_cc[VEOL], InChar)) {\r | |
139 | EchoIsOK = FALSE; // Buffer, but don't echo this character\r | |
140 | }\r | |
141 | else if(CCEQ(Termio->c_cc[VERASE], InChar)) {\r | |
142 | InChar = IIO_ECHO_ERASE;\r | |
143 | Activate = FALSE;\r | |
144 | }\r | |
145 | else if(CCEQ(Termio->c_cc[VKILL], InChar)) {\r | |
146 | InChar = IIO_ECHO_KILL;\r | |
147 | Activate = FALSE;\r | |
148 | }\r | |
149 | else {\r | |
150 | if((InChar < TtySpecKeyMin) || (InChar >= TtyFunKeyMax)) {\r | |
151 | Activate = FALSE;\r | |
152 | }\r | |
153 | }\r | |
154 | /** The Echo function is responsible for:\r | |
155 | * Adding the character to the input buffer, if appropriate.\r | |
156 | * Removing characters from the input buffer for ERASE and KILL processing.\r | |
157 | * Visually removing characters from the screen if ECHOE is set.\r | |
158 | * Ensuring one can not backspace beyond the beginning of the input text.\r | |
159 | * Sending final echo strings to output.\r | |
160 | **/\r | |
161 | (void)This->Echo(fpOut, (wchar_t)InChar, EchoIsOK);\r | |
162 | NumRead = InBuf->Count(InBuf, AsElements);\r | |
163 | } while((NumRead < MAX_INPUT) &&\r | |
164 | (Activate == FALSE));\r | |
165 | \r | |
166 | return (ssize_t)NumRead;\r | |
167 | }\r |