]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/Uefi/InteractiveIO/CanonRead.c
StdLib: Fix IIO_Write() to return the number of bytes consumed, not characters output.
[mirror_edk2.git] / StdLib / LibC / Uefi / InteractiveIO / CanonRead.c
CommitLineData
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
35ssize_t\r
36IIO_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