StdLib: Add terminal type line editing (Interactive IO) for console devices.
Adds a subset of the terminal I/O capabilities described in the Single Unix Specification, V4. Supports: Erase previous character. Default is Backspace or ^H Erase line. Default is ^U TAB characters are supported and, by default, are rendered as 8 spaces. They will still be read as a single TAB character. Both Canonical and Non-Canonical modes are supported. If a terminal device is opened with O_TTY_INIT in the mode, the device will be initialized to "sane" values for interactive use. It will be in Canonical mode, Enter will be translated to NewLine and on output, a NewLine is translated to CRLF. Echoing will be on, control characters are output as ^X, and TABs are expanded. See the new <sys/termios.h> file for more information. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: daryl.mcdaniel@intel.com Reviewed-by: erik.c.bjorge@intel.com Reviewed-by: leroy.p.leahy@intel.com Reviewed-by: lee.g.rosenbaum@intel.com Reviewed-by: jaben.carsey@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13989 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -3,6 +3,13 @@
|
||||
|
||||
Manipulates abstractions for stdin, stdout, stderr.
|
||||
|
||||
This device is a WIDE device and this driver returns WIDE
|
||||
characters. It this the responsibility of the caller to convert between
|
||||
narrow and wide characters in order to perform the desired operations.
|
||||
|
||||
The devices status as a wide device is indicatd by _S_IWTTY being set in
|
||||
f_iflags.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
@@ -30,6 +37,7 @@
|
||||
#include <unistd.h>
|
||||
#include <kfile.h>
|
||||
#include <Device/Device.h>
|
||||
#include <Device/IIO.h>
|
||||
#include <MainData.h>
|
||||
|
||||
static const CHAR16* const
|
||||
@@ -46,7 +54,7 @@ static const int stdioFlags[NUM_SPECIAL] = {
|
||||
static DeviceNode *ConNode[NUM_SPECIAL];
|
||||
static ConInstance *ConInstanceList;
|
||||
|
||||
static wchar_t *ConReadBuf;
|
||||
static cIIO *IIO;
|
||||
|
||||
/* Flags settable by Ioctl */
|
||||
static BOOLEAN TtyCooked;
|
||||
@@ -58,10 +66,10 @@ static BOOLEAN TtyEcho;
|
||||
large enough to hold the converted results. It is guaranteed
|
||||
that there will be fewer than n characters placed in dest.
|
||||
|
||||
@param dest WCS buffer to receive the converted string.
|
||||
@param buf MBCS string to convert to WCS.
|
||||
@param n Number of BYTES contained in buf.
|
||||
@param Cs Pointer to the character state object for this stream
|
||||
@param[out] dest WCS buffer to receive the converted string.
|
||||
@param[in] buf MBCS string to convert to WCS.
|
||||
@param[in] n Number of BYTES contained in buf.
|
||||
@param[in,out] Cs Pointer to the character state object for this stream
|
||||
|
||||
@return The number of BYTES consumed from buf.
|
||||
**/
|
||||
@@ -94,6 +102,13 @@ WideTtyCvt( CHAR16 *dest, const char *buf, ssize_t n, mbstate_t *Cs)
|
||||
return i;
|
||||
}
|
||||
|
||||
/** Close an open file.
|
||||
|
||||
@param[in] filp Pointer to the file descriptor structure for this file.
|
||||
|
||||
@retval 0 The file has been successfully closed.
|
||||
@retval -1 filp does not point to a valid console descriptor.
|
||||
**/
|
||||
static
|
||||
int
|
||||
EFIAPI
|
||||
@@ -106,13 +121,25 @@ da_ConClose(
|
||||
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
errno = EINVAL;
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1; // Looks like a bad File Descriptor pointer
|
||||
}
|
||||
gMD->StdIo[Stream->InstanceNum] = NULL; // Mark the stream as closed
|
||||
return RETURN_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Position the console cursor to the coordinates specified by Position.
|
||||
|
||||
@param[in] filp Pointer to the file descriptor structure for this file.
|
||||
@param[in] Position A value containing the target X and Y coordinates.
|
||||
@param[in] whence Ignored by the Console device.
|
||||
|
||||
@retval Position Success. Returns a copy of the Position argument.
|
||||
@retval -1 filp is not associated with a valid console stream.
|
||||
@retval -1 This console stream is attached to stdin.
|
||||
@retval -1 The SetCursorPosition operation failed.
|
||||
**/
|
||||
static
|
||||
off_t
|
||||
EFIAPI
|
||||
@@ -155,11 +182,14 @@ da_ConSeek(
|
||||
|
||||
/* Write a NULL terminated WCS to the EFI console.
|
||||
|
||||
@param[in,out] BufferSize Number of bytes in Buffer. Set to zero if
|
||||
the string couldn't be displayed.
|
||||
NOTE: The UEFI Console is a wide device, _S_IWTTY, so characters received
|
||||
by da_ConWrite are WIDE characters. It is the responsibility of the
|
||||
higher-level function(s) to perform any necessary conversions.
|
||||
|
||||
@param[in,out] BufferSize Number of characters in Buffer.
|
||||
@param[in] Buffer The WCS string to be displayed
|
||||
|
||||
@return The number of BYTES written. Because of MBCS, this may be more than number of characters.
|
||||
@return The number of Characters written.
|
||||
*/
|
||||
static
|
||||
ssize_t
|
||||
@@ -174,8 +204,10 @@ da_ConWrite(
|
||||
EFI_STATUS Status;
|
||||
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
|
||||
ConInstance *Stream;
|
||||
ssize_t NumBytes;
|
||||
ssize_t NumChar;
|
||||
XY_OFFSET CursorPos;
|
||||
|
||||
NumChar = -1;
|
||||
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
@@ -190,35 +222,45 @@ da_ConWrite(
|
||||
// Everything is OK to do the write.
|
||||
Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;
|
||||
|
||||
// Convert string from MBCS to WCS and translate \n to \r\n.
|
||||
NumBytes = WideTtyCvt(gMD->UString, (const char *)Buffer, (ssize_t)BufferSize, &Stream->CharState);
|
||||
BufferSize = NumBytes;
|
||||
Status = EFI_SUCCESS;
|
||||
if(Position != NULL) {
|
||||
CursorPos.Offset = *Position;
|
||||
|
||||
Status = Proto->SetCursorPosition(Proto,
|
||||
(INTN)CursorPos.XYpos.Column,
|
||||
(INTN)CursorPos.XYpos.Row);
|
||||
|
||||
// Send the Unicode buffer to the console
|
||||
Status = Proto->OutputString( Proto, gMD->UString);
|
||||
// Depending on status, update BufferSize and return
|
||||
if(RETURN_ERROR(Status)) {
|
||||
BufferSize = 0; // We don't really know how many characters made it out
|
||||
}
|
||||
else {
|
||||
//BufferSize = NumBytes;
|
||||
Stream->NumWritten += NumBytes;
|
||||
if(!RETURN_ERROR(Status)) {
|
||||
// Send the Unicode buffer to the console
|
||||
Status = Proto->OutputString( Proto, (CHAR16 *)Buffer);
|
||||
}
|
||||
|
||||
// Depending on status, update BufferSize and return
|
||||
if(!RETURN_ERROR(Status)) {
|
||||
//BufferSize = NumChar;
|
||||
NumChar = BufferSize;
|
||||
Stream->NumWritten += NumChar;
|
||||
}
|
||||
EFIerrno = Status; // Make error reason available to caller
|
||||
return BufferSize;
|
||||
return NumChar;
|
||||
}
|
||||
|
||||
/** Read characters from the console input device.
|
||||
/** Read a wide character from the console input device.
|
||||
|
||||
@param[in,out] filp Pointer to file descriptor for this file.
|
||||
@param[in,out] offset Ignored.
|
||||
NOTE: The UEFI Console is a wide device, _S_IWTTY, so characters returned
|
||||
by da_ConRead are WIDE characters. It is the responsibility of the
|
||||
higher-level function(s) to perform any necessary conversions.
|
||||
|
||||
@param[in,out] BufferSize Number of characters in Buffer.
|
||||
@param[in] filp Pointer to file descriptor for this file.
|
||||
@param[in] offset Ignored.
|
||||
@param[in] BufferSize Buffer size, in bytes.
|
||||
@param[out] Buffer Buffer in which to place the read characters.
|
||||
|
||||
@return Number of bytes actually placed into Buffer.
|
||||
|
||||
@todo Handle encodings other than ASCII-7 and UEFI.
|
||||
@retval -1 An error has occurred. Reason in errno and EFIerrno.
|
||||
@retval -1 No data is available. errno is set to EAGAIN
|
||||
@retval 1 One wide character has been placed in Buffer
|
||||
**/
|
||||
static
|
||||
ssize_t
|
||||
@@ -232,84 +274,80 @@ da_ConRead(
|
||||
{
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;
|
||||
ConInstance *Stream;
|
||||
wchar_t *OutPtr;
|
||||
EFI_INPUT_KEY Key;
|
||||
UINTN NumChar;
|
||||
UINTN Edex;
|
||||
cIIO *Self;
|
||||
EFI_INPUT_KEY Key = {0,0};
|
||||
EFI_STATUS Status = RETURN_SUCCESS;
|
||||
UINTN i;
|
||||
char EchoBuff[MB_CUR_MAX + 1];
|
||||
int NumEcho;
|
||||
UINTN Edex;
|
||||
ssize_t NumRead;
|
||||
int Flags;
|
||||
wchar_t RetChar; // Default to No Data
|
||||
|
||||
NumRead = -1;
|
||||
if(BufferSize < sizeof(wchar_t)) {
|
||||
errno = EINVAL; // Buffer is too small to hold one character
|
||||
}
|
||||
else {
|
||||
Self = (cIIO *)filp->devdata;
|
||||
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1; // Looks like a bad This pointer
|
||||
}
|
||||
if(Stream->InstanceNum != STDIN_FILENO) {
|
||||
// Read only valid for stdin
|
||||
EFIerrno = RETURN_UNSUPPORTED;
|
||||
return -1;
|
||||
}
|
||||
// It looks like things are OK for trying to read
|
||||
// We will accumulate *BufferSize characters or until we encounter
|
||||
// an "activation" character. Currently any control character.
|
||||
Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;
|
||||
OutPtr = ConReadBuf;
|
||||
NumChar = (BufferSize > MAX_INPUT)? MAX_INPUT : BufferSize;
|
||||
i = 0;
|
||||
do {
|
||||
Flags = filp->Oflags;
|
||||
if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {
|
||||
// No data pending in the Un-get buffer. Get a char from the hardware.
|
||||
if((Flags & O_NONBLOCK) == 0) {
|
||||
// Read a byte in Blocking mode
|
||||
Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
EFIerrno = Status;
|
||||
if(Status != EFI_SUCCESS) {
|
||||
errno = EINVAL;
|
||||
}
|
||||
else {
|
||||
Status = Proto->ReadKeyStroke(Proto, &Key);
|
||||
if(Status != RETURN_SUCCESS) {
|
||||
break;
|
||||
if(Status == EFI_SUCCESS) {
|
||||
NumRead = 1; // Indicate that Key holds the data
|
||||
}
|
||||
else {
|
||||
errno = EIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Read a byte in Non-Blocking mode
|
||||
Status = Proto->ReadKeyStroke(Proto, &Key);
|
||||
EFIerrno = Status;
|
||||
if(Status == EFI_SUCCESS) {
|
||||
// Got a keystroke.
|
||||
NumRead = 1; // Indicate that Key holds the data
|
||||
}
|
||||
else if(Status == EFI_NOT_READY) {
|
||||
// Keystroke data is not available
|
||||
errno = EAGAIN;
|
||||
}
|
||||
else {
|
||||
// Hardware error
|
||||
errno = EIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Use the data in the Un-get buffer
|
||||
Key.ScanCode = Stream->UnGetKey.ScanCode;
|
||||
Key.UnicodeChar = Stream->UnGetKey.UnicodeChar;
|
||||
Stream->UnGetKey.ScanCode = SCAN_NULL;
|
||||
Stream->UnGetKey.UnicodeChar = CHAR_NULL;
|
||||
NumRead = 1; // Indicate that Key holds the data
|
||||
}
|
||||
if(Key.ScanCode == SCAN_NULL) {
|
||||
NumEcho = 0;
|
||||
if(TtyCooked && (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
|
||||
*OutPtr++ = CHAR_LINEFEED;
|
||||
NumEcho = wctomb(EchoBuff, CHAR_LINEFEED);
|
||||
// If we have data, prepare it for return.
|
||||
if(NumRead == 1) {
|
||||
RetChar = Key.UnicodeChar;
|
||||
if((RetChar == 0) && ((Self->Termio.c_iflag & IGNSPEC) == 0)) {
|
||||
// Must be a control, function, or other non-printable key.
|
||||
// Map it into the Platform portion of the Unicode private use area
|
||||
RetChar = (Key.ScanCode == 0) ? 0 : 0xF900U - Key.ScanCode;
|
||||
}
|
||||
else {
|
||||
*OutPtr++ = Key.UnicodeChar;
|
||||
NumEcho = wctomb(EchoBuff, Key.UnicodeChar);
|
||||
}
|
||||
++i;
|
||||
EchoBuff[NumEcho] = 0; /* Terminate the Echo buffer */
|
||||
if(TtyEcho) {
|
||||
/* Echo the character just input */
|
||||
da_ConWrite(&gMD->fdarray[STDOUT_FILENO], NULL, 2, EchoBuff);
|
||||
*((wchar_t *)Buffer) = RetChar;
|
||||
}
|
||||
}
|
||||
if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code
|
||||
break;
|
||||
}
|
||||
} while(i < NumChar);
|
||||
|
||||
*OutPtr = L'\0'; // Terminate the input buffer
|
||||
|
||||
/* Convert the input buffer and place in Buffer.
|
||||
If the fully converted input buffer won't fit, write what will and
|
||||
leave the rest in ConReadBuf with ConReadLeft indicating how many
|
||||
unconverted characters remain in ConReadBuf.
|
||||
*/
|
||||
NumEcho = (int)wcstombs(Buffer, ConReadBuf, BufferSize); /* Re-use NumEcho to hold number of bytes in Buffer */
|
||||
/* More work needs to be done before locales other than C can be supported. */
|
||||
|
||||
EFIerrno = Status;
|
||||
return (ssize_t)NumEcho; // Will be 0 if we didn't get a key
|
||||
return NumRead;
|
||||
}
|
||||
|
||||
/** Console-specific helper function for the fstat() function.
|
||||
@@ -320,6 +358,14 @@ da_ConRead(
|
||||
st_blksize Set to 1 since this is a character device
|
||||
|
||||
All other members of the stat structure are left unchanged.
|
||||
|
||||
@param[in] filp Pointer to file descriptor for this file.
|
||||
@param[out] Buffer Pointer to a stat structure to receive the information.
|
||||
@param[in,out] Something Ignored.
|
||||
|
||||
@retval 0 Successful completion.
|
||||
@retval -1 Either filp is not associated with a console stream, or
|
||||
Buffer is NULL. errno is set to EINVAL.
|
||||
**/
|
||||
static
|
||||
int
|
||||
@@ -343,6 +389,7 @@ da_ConStat(
|
||||
if ((Stream->Cookie != CON_COOKIE) || // Cookie == 'IoAb'
|
||||
(Buffer == NULL))
|
||||
{
|
||||
errno = EINVAL;
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return -1;
|
||||
}
|
||||
@@ -378,6 +425,14 @@ da_ConStat(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Console-specific helper for the ioctl system call.
|
||||
|
||||
The console device does not directly participate in ioctl operations.
|
||||
This function completes the device abstraction and returns an error value
|
||||
to indicate that the function is not supported for this device.
|
||||
|
||||
@retval -1 Function is not supported for this device.
|
||||
**/
|
||||
static
|
||||
int
|
||||
EFIAPI
|
||||
@@ -387,10 +442,21 @@ da_ConIoctl(
|
||||
va_list argp
|
||||
)
|
||||
{
|
||||
return -EPERM;
|
||||
errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Open an abstract Console Device.
|
||||
|
||||
@param[in] DevNode Pointer to the Device control structure for this stream.
|
||||
@param[in] filp Pointer to the new file control structure for this stream.
|
||||
@param[in] DevInstance Not used for the console device.
|
||||
@param[in] Path Not used for the console device.
|
||||
@param[in] MPath Not used for the console device.
|
||||
|
||||
@retval 0 This console stream has been successfully opened.
|
||||
@retval -1 The DevNode or filp pointer is NULL.
|
||||
@retval -1 DevNode does not point to a valid console stream device.
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
@@ -403,36 +469,57 @@ da_ConOpen(
|
||||
)
|
||||
{
|
||||
ConInstance *Stream;
|
||||
UINT32 Instance;
|
||||
int RetVal = -1;
|
||||
|
||||
if((filp == NULL) ||
|
||||
(DevNode == NULL))
|
||||
if((filp != NULL) &&
|
||||
(DevNode != NULL))
|
||||
{
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
Stream = (ConInstance *)DevNode->InstanceList;
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
if(Stream->Cookie == CON_COOKIE)
|
||||
{
|
||||
Instance = Stream->InstanceNum;
|
||||
if(Instance < NUM_SPECIAL) {
|
||||
gMD->StdIo[Instance] = Stream;
|
||||
filp->f_iflags |= (_S_IFCHR | _S_ITTY | _S_IWTTY | _S_ICONSOLE);
|
||||
filp->f_offset = 0;
|
||||
filp->f_ops = &Stream->Abstraction;
|
||||
filp->devdata = (void *)IIO;
|
||||
RetVal = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (RetVal < 0) {
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
errno = EINVAL;
|
||||
return -1; // Looks like a bad This pointer
|
||||
}
|
||||
gMD->StdIo[Stream->InstanceNum] = Stream;
|
||||
filp->f_iflags |= (S_IFREG | _S_IFCHR | _S_ICONSOLE);
|
||||
filp->f_offset = 0;
|
||||
filp->f_ops = &Stream->Abstraction;
|
||||
return RetVal;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <sys/poll.h>
|
||||
/* Returns a bit mask describing which operations could be completed immediately.
|
||||
|
||||
Testable Events for this device are:
|
||||
(POLLIN | POLLRDNORM) A Unicode character is available to read
|
||||
(POLLIN) A ScanCode is ready.
|
||||
(POLLOUT) The device is ready for output - always set on stdout and stderr.
|
||||
|
||||
Non-testable Events which are only valid in return values are:
|
||||
POLLERR The specified device is not one of stdin, stdout, or stderr.
|
||||
POLLHUP The specified stream has been disconnected
|
||||
POLLNVAL da_ConPoll was called with an invalid parameter.
|
||||
|
||||
NOTE: The "Events" handled by this function are not UEFI events.
|
||||
|
||||
@param[in] filp Pointer to the file control structure for this stream.
|
||||
@param[in] events A bit mask identifying the events to be examined
|
||||
for this device.
|
||||
|
||||
@return Returns a bit mask comprised of both testable and non-testable
|
||||
event codes indicating both the state of the operation and the
|
||||
status of the device.
|
||||
*/
|
||||
static
|
||||
short
|
||||
@@ -450,6 +537,7 @@ da_ConPoll(
|
||||
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
|
||||
// Quick check to see if Stream looks reasonable
|
||||
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
|
||||
errno = EINVAL;
|
||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||
return POLLNVAL; // Looks like a bad filp pointer
|
||||
}
|
||||
@@ -495,15 +583,18 @@ __Cons_construct(
|
||||
)
|
||||
{
|
||||
ConInstance *Stream;
|
||||
RETURN_STATUS Status = RETURN_SUCCESS;
|
||||
RETURN_STATUS Status;
|
||||
int i;
|
||||
|
||||
Status = RETURN_OUT_OF_RESOURCES;
|
||||
ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance));
|
||||
ConReadBuf = (wchar_t *)AllocateZeroPool((MAX_INPUT + 1) * sizeof(wchar_t));
|
||||
if((ConInstanceList == NULL) || (ConReadBuf == NULL)) {
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
if(ConInstanceList != NULL) {
|
||||
IIO = New_cIIO();
|
||||
if(IIO == NULL) {
|
||||
FreePool(ConInstanceList);
|
||||
}
|
||||
|
||||
else {
|
||||
Status = RETURN_SUCCESS;
|
||||
for( i = 0; i < NUM_SPECIAL; ++i) {
|
||||
// Get pointer to instance.
|
||||
Stream = &ConInstanceList[i];
|
||||
@@ -553,9 +644,10 @@ __Cons_construct(
|
||||
if(Stream->Dev == NULL) {
|
||||
continue; // No device for this stream.
|
||||
}
|
||||
ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream, 1, sizeof(ConInstance), stdioFlags[i]);
|
||||
ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream,
|
||||
1, sizeof(ConInstance), stdioFlags[i]);
|
||||
if(ConNode[i] == NULL) {
|
||||
Status = EFIerrno;
|
||||
Status = EFIerrno; // Grab error code that DevRegister produced.
|
||||
break;
|
||||
}
|
||||
Stream->Parent = ConNode[i];
|
||||
@@ -563,7 +655,8 @@ __Cons_construct(
|
||||
/* Initialize Ioctl flags until Ioctl is really implemented. */
|
||||
TtyCooked = TRUE;
|
||||
TtyEcho = TRUE;
|
||||
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -584,15 +677,16 @@ __Cons_deconstruct(
|
||||
if(ConInstanceList != NULL) {
|
||||
FreePool(ConInstanceList);
|
||||
}
|
||||
if(ConReadBuf != NULL) {
|
||||
FreePool(ConReadBuf);
|
||||
if(IIO != NULL) {
|
||||
IIO->Delete(IIO);
|
||||
IIO = NULL;
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
/* ######################################################################### */
|
||||
#if 0 /* Not implemented for Console */
|
||||
#if 0 /* Not implemented (yet?) for Console */
|
||||
|
||||
static
|
||||
int
|
||||
|
Reference in New Issue
Block a user