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:
161
StdLib/LibC/Uefi/InteractiveIO/CanonRead.c
Normal file
161
StdLib/LibC/Uefi/InteractiveIO/CanonRead.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/** @file
|
||||
Canonical Interactive Input Function.
|
||||
|
||||
The functions assume that isatty() is TRUE at the time they are called.
|
||||
|
||||
Copyright (c) 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 which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <sys/termios.h>
|
||||
#include <Device/IIO.h>
|
||||
#include <MainData.h>
|
||||
#include "IIOutilities.h"
|
||||
#include "IIOechoCtrl.h"
|
||||
|
||||
/** Read a line from the input file in canonical mode.
|
||||
Perform echoing and input processing as directed by the termios flags.
|
||||
|
||||
@param[in] filp A pointer to a file descriptor structure.
|
||||
|
||||
@return The number of characters in the input buffer, or -1 if there
|
||||
was an error.
|
||||
**/
|
||||
ssize_t
|
||||
IIO_CanonRead (
|
||||
struct __filedes *filp
|
||||
)
|
||||
{
|
||||
cIIO *This;
|
||||
cFIFO *InBuf;
|
||||
struct termios *Termio;
|
||||
struct __filedes *fpOut;
|
||||
size_t NumRead;
|
||||
wint_t InChar;
|
||||
tcflag_t IFlag;
|
||||
tcflag_t LFlag;
|
||||
BOOLEAN EchoIsOK;
|
||||
BOOLEAN Activate;
|
||||
BOOLEAN FirstRead;
|
||||
int OutMode;
|
||||
UINTN MaxColumn;
|
||||
UINTN MaxRow;
|
||||
|
||||
NumRead = MAX_INPUT; // Workaround "potentially uninitialized" warning
|
||||
EchoIsOK = FALSE;
|
||||
FirstRead = TRUE;
|
||||
This = filp->devdata;
|
||||
Termio = &This->Termio;
|
||||
InBuf = This->InBuf;
|
||||
|
||||
// Get a copy of the flags we are going to use
|
||||
IFlag = Termio->c_iflag;
|
||||
LFlag = Termio->c_lflag;
|
||||
|
||||
/* Determine what the current screen size is. Also validates the output device. */
|
||||
OutMode = IIO_GetOutputSize(STDOUT_FILENO, &MaxColumn, &MaxRow);
|
||||
if(OutMode >= 0) {
|
||||
/* Set the maximum screen dimensions. */
|
||||
This->MaxColumn = MaxColumn;
|
||||
This->MaxRow = MaxRow;
|
||||
|
||||
/* Record where the cursor is at the beginning of this Input operation.
|
||||
The currently set stdout device is used to determine this. If there is
|
||||
no stdout, or stdout is not an interactive device, nothing is recorded.
|
||||
*/
|
||||
if (IIO_GetCursorPosition(STDOUT_FILENO, &This->InitialXY.Column, &This->InitialXY.Row) >= 0) {
|
||||
This->CurrentXY.Column = This->InitialXY.Column;
|
||||
This->CurrentXY.Row = This->InitialXY.Row;
|
||||
EchoIsOK = TRUE; // Can only echo to stdout
|
||||
}
|
||||
}
|
||||
|
||||
// For now, we only echo to stdout.
|
||||
fpOut = &gMD->fdarray[STDOUT_FILENO];
|
||||
|
||||
// Input and process characters until BufferSize is exhausted.
|
||||
do {
|
||||
InChar = IIO_GetInChar(filp, FirstRead);
|
||||
FirstRead = FALSE;
|
||||
Activate = TRUE;
|
||||
if(InChar == CHAR_CARRIAGE_RETURN) {
|
||||
if((IFlag & IGNCR) != 0) {
|
||||
continue; // Restart the do loop, discarding the CR
|
||||
}
|
||||
else if((IFlag & ICRNL) != 0) {
|
||||
InChar = L'\n';
|
||||
}
|
||||
}
|
||||
else if(InChar == CHAR_LINEFEED) {
|
||||
if((IFlag & INLCR) != 0) {
|
||||
InChar = L'\r';
|
||||
}
|
||||
}
|
||||
else if(CCEQ(Termio->c_cc[VINTR], InChar)) {
|
||||
if((LFlag & ISIG) != 0) {
|
||||
// Raise Signal
|
||||
// Flush Input Buffer
|
||||
// Return to caller
|
||||
InChar = IIO_ECHO_DISCARD;
|
||||
errno = EINTR;
|
||||
}
|
||||
else {
|
||||
Activate = FALSE;
|
||||
}
|
||||
}
|
||||
else if(CCEQ(Termio->c_cc[VQUIT], InChar)) {
|
||||
if((LFlag & ISIG) != 0) {
|
||||
// Raise Signal
|
||||
// Flush Input Buffer
|
||||
// Return to caller
|
||||
InChar = IIO_ECHO_DISCARD;
|
||||
errno = EINTR;
|
||||
}
|
||||
else {
|
||||
Activate = FALSE;
|
||||
}
|
||||
}
|
||||
else if(CCEQ(Termio->c_cc[VEOF], InChar)) {
|
||||
InChar = WEOF;
|
||||
}
|
||||
else if(CCEQ(Termio->c_cc[VEOL], InChar)) {
|
||||
EchoIsOK = FALSE; // Buffer, but don't echo this character
|
||||
}
|
||||
else if(CCEQ(Termio->c_cc[VERASE], InChar)) {
|
||||
InChar = IIO_ECHO_ERASE;
|
||||
Activate = FALSE;
|
||||
}
|
||||
else if(CCEQ(Termio->c_cc[VKILL], InChar)) {
|
||||
InChar = IIO_ECHO_KILL;
|
||||
Activate = FALSE;
|
||||
}
|
||||
else {
|
||||
if((InChar < TtySpecKeyMin) || (InChar >= TtyFunKeyMax)) {
|
||||
Activate = FALSE;
|
||||
}
|
||||
}
|
||||
/** The Echo function is responsible for:
|
||||
* Adding the character to the input buffer, if appropriate.
|
||||
* Removing characters from the input buffer for ERASE and KILL processing.
|
||||
* Visually removing characters from the screen if ECHOE is set.
|
||||
* Ensuring one can not backspace beyond the beginning of the input text.
|
||||
* Sending final echo strings to output.
|
||||
**/
|
||||
(void)This->Echo(fpOut, (wchar_t)InChar, EchoIsOK);
|
||||
NumRead = InBuf->Count(InBuf, AsElements);
|
||||
} while((NumRead < MAX_INPUT) &&
|
||||
(Activate == FALSE));
|
||||
|
||||
return (ssize_t)NumRead;
|
||||
}
|
373
StdLib/LibC/Uefi/InteractiveIO/IIO.c
Normal file
373
StdLib/LibC/Uefi/InteractiveIO/IIO.c
Normal file
@@ -0,0 +1,373 @@
|
||||
/** @file
|
||||
Definitions for the Interactive IO library.
|
||||
|
||||
The functions assume that isatty() is TRUE at the time they are called.
|
||||
|
||||
Copyright (c) 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 which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <sys/termios.h>
|
||||
#include <Device/IIO.h>
|
||||
#include <MainData.h>
|
||||
#include "IIOutilities.h"
|
||||
#include "IIOechoCtrl.h"
|
||||
|
||||
/** Read from an Interactive IO device.
|
||||
|
||||
NOTE: If _S_IWTTY is set, the internal buffer contains WIDE characters.
|
||||
They will need to be converted to MBCS when returned.
|
||||
|
||||
Input is line buffered if ICANON is set,
|
||||
otherwise MIN determines how many characters to input.
|
||||
Currently MIN is always zero, meaning 0 or 1 character is input in
|
||||
noncanonical mode.
|
||||
|
||||
@param[in] filp Pointer to the descriptor of the device (file) to be read.
|
||||
@param[in] BufferSize Maximum number of bytes to be returned to the caller.
|
||||
@param[out] Buffer Pointer to the buffer where the input is to be stored.
|
||||
|
||||
@retval -1 An error occurred. No data is available.
|
||||
@retval 0 No data was available. Try again later.
|
||||
@retval >0 The number of bytes consumed by the returned data.
|
||||
**/
|
||||
static
|
||||
ssize_t
|
||||
EFIAPI
|
||||
IIO_Read(
|
||||
struct __filedes *filp,
|
||||
size_t BufferSize,
|
||||
VOID *Buffer
|
||||
)
|
||||
{
|
||||
cIIO *This;
|
||||
ssize_t NumRead;
|
||||
tcflag_t Flags;
|
||||
size_t XlateSz;
|
||||
size_t Needed;
|
||||
|
||||
NumRead = -1;
|
||||
This = filp->devdata;
|
||||
if(This != NULL) {
|
||||
Flags = This->Termio.c_lflag;
|
||||
if(Flags & ICANON) {
|
||||
NumRead = IIO_CanonRead(filp);
|
||||
}
|
||||
else {
|
||||
NumRead = IIO_NonCanonRead(filp);
|
||||
}
|
||||
// At this point, the input has been accumulated in the input buffer.
|
||||
if(filp->f_iflags & _S_IWTTY) {
|
||||
// Data in InBuf is wide characters. Convert to MBCS
|
||||
// First, convert into a linear buffer
|
||||
NumRead = This->InBuf->Copy(This->InBuf, gMD->UString2, (INT32)UNICODE_STRING_MAX-1);
|
||||
gMD->UString2[NumRead] = 0; // Ensure that the buffer is terminated
|
||||
// Determine the needed space
|
||||
XlateSz = EstimateWtoM((const wchar_t *)gMD->UString2, BufferSize, &Needed);
|
||||
|
||||
// Now translate this into MBCS in Buffer
|
||||
NumRead = wcstombs((char *)Buffer, (const wchar_t *)gMD->UString2, XlateSz);
|
||||
|
||||
// Consume the translated characters
|
||||
(void)This->InBuf->Flush(This->InBuf, Needed);
|
||||
}
|
||||
else {
|
||||
// Data in InBuf is narrow characters. Use verbatim.
|
||||
NumRead = This->InBuf->Read(This->InBuf, Buffer, (INT32)BufferSize);
|
||||
}
|
||||
}
|
||||
return NumRead;
|
||||
}
|
||||
|
||||
/** Process characters from buffer buf and write them to the output device
|
||||
specified by filp.
|
||||
|
||||
@param[in] filp Pointer to a file descriptor structure.
|
||||
@param[in] buf Pointer to the MBCS string to be output.
|
||||
@param[in] N Number of bytes in buf.
|
||||
|
||||
@retval >=0 Number of bytes sent to the output device.
|
||||
**/
|
||||
static
|
||||
ssize_t
|
||||
EFIAPI
|
||||
IIO_Write(
|
||||
struct __filedes *filp,
|
||||
const char *buf,
|
||||
ssize_t N
|
||||
)
|
||||
{
|
||||
cIIO *This;
|
||||
cFIFO *OutBuf;
|
||||
mbstate_t *OutState;
|
||||
char *MbcsPtr;
|
||||
ssize_t NumWritten;
|
||||
ssize_t NumProc;
|
||||
size_t CharLen;
|
||||
UINTN MaxColumn;
|
||||
UINTN MaxRow;
|
||||
wchar_t OutChar[2]; // Just in case we run into 4-byte MBCS character
|
||||
int OutMode;
|
||||
|
||||
errno = 0; // indicate no error as default
|
||||
NumWritten = -1;
|
||||
|
||||
/* Determine what the current screen size is. Also validates the output device. */
|
||||
OutMode = IIO_GetOutputSize(filp->MyFD, &MaxColumn, &MaxRow);
|
||||
|
||||
This = filp->devdata;
|
||||
if((This != NULL) && (OutMode >= 0)) {
|
||||
if(filp->MyFD == STDERR_FILENO) {
|
||||
OutBuf = This->ErrBuf;
|
||||
OutState = &This->ErrState;
|
||||
}
|
||||
else {
|
||||
OutBuf = This->OutBuf;
|
||||
OutState = &This->OutState;
|
||||
}
|
||||
|
||||
/* Set the maximum screen dimensions. */
|
||||
This->MaxColumn = MaxColumn;
|
||||
This->MaxRow = MaxRow;
|
||||
|
||||
/* Record where the cursor is at the beginning of the Output operation. */
|
||||
(void)IIO_GetCursorPosition(filp->MyFD, &This->InitialXY.Column, &This->InitialXY.Row);
|
||||
This->CurrentXY.Column = This->InitialXY.Column;
|
||||
This->CurrentXY.Row = This->InitialXY.Row;
|
||||
|
||||
|
||||
NumWritten = 0;
|
||||
OutChar[0] = (wchar_t)buf[0];
|
||||
while((OutChar[0] != 0) && (NumWritten < N)) {
|
||||
CharLen = mbrtowc(OutChar, (const char *)&buf[NumWritten], MB_CUR_MAX, OutState);
|
||||
NumProc = IIO_WriteOne(filp, OutBuf, OutChar[0]);
|
||||
if(NumProc > 0) {
|
||||
// Successfully processed and buffered one character
|
||||
NumWritten += CharLen; // Index of start of next character
|
||||
}
|
||||
else if(NumProc == -1) {
|
||||
// Encoding Error
|
||||
(void)mbrtowc(NULL, NULL, 1, OutState); // Re-Initialize the conversion state
|
||||
errno = EILSEQ;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// Last character was incomplete
|
||||
break;
|
||||
}
|
||||
}
|
||||
// At this point, the characters to write are in OutBuf
|
||||
// First, linearize the buffer
|
||||
NumWritten = OutBuf->Copy(OutBuf, gMD->UString, UNICODE_STRING_MAX-1);
|
||||
gMD->UString[NumWritten] = 0; // Ensure that the buffer is terminated
|
||||
|
||||
if(filp->f_iflags & _S_IWTTY) {
|
||||
// Output device expects wide characters, Output what we have
|
||||
NumWritten = filp->f_ops->fo_write(filp, NULL, NumWritten, gMD->UString);
|
||||
}
|
||||
else {
|
||||
// Output device expects narrow characters, convert to MBCS
|
||||
MbcsPtr = (char *)gMD->UString2;
|
||||
// Determine the needed space
|
||||
NumProc = (ssize_t)EstimateWtoM((const wchar_t *)gMD->UString, UNICODE_STRING_MAX * sizeof(wchar_t), &CharLen);
|
||||
|
||||
// Now translate this into MBCS in Buffer
|
||||
NumWritten = wcstombs(MbcsPtr, (const wchar_t *)gMD->UString, NumProc);
|
||||
MbcsPtr[NumWritten] = 0; // Ensure the buffer is terminated
|
||||
|
||||
// Send the MBCS buffer to Output
|
||||
NumWritten = filp->f_ops->fo_write(filp, NULL, NumWritten, MbcsPtr);
|
||||
}
|
||||
// Consume the translated characters
|
||||
(void)OutBuf->Flush(OutBuf, NumWritten);
|
||||
}
|
||||
else {
|
||||
if(This == NULL) {
|
||||
errno = EINVAL;
|
||||
}
|
||||
// Otherwise, errno is already set.
|
||||
}
|
||||
return NumWritten;
|
||||
}
|
||||
|
||||
/** Echo a character to an output device.
|
||||
Performs translation and edit processing depending upon termios flags.
|
||||
|
||||
@param[in] filp A pointer to a file descriptor structure.
|
||||
@param[in] EChar The character to echo.
|
||||
@param[in] EchoIsOK TRUE if the caller has determined that characters
|
||||
should be echoed. Otherwise, just buffer.
|
||||
|
||||
@return Returns the number of characters actually output.
|
||||
**/
|
||||
static
|
||||
ssize_t
|
||||
EFIAPI
|
||||
IIO_Echo(
|
||||
struct __filedes *filp,
|
||||
wchar_t EChar,
|
||||
BOOLEAN EchoIsOK
|
||||
)
|
||||
{
|
||||
cIIO *This;
|
||||
ssize_t NumWritten;
|
||||
cFIFO *OutBuf;
|
||||
char *MbcsPtr;
|
||||
ssize_t NumProc;
|
||||
tcflag_t LFlags;
|
||||
|
||||
NumWritten = -1;
|
||||
This = filp->devdata;
|
||||
if(This != NULL) {
|
||||
OutBuf = This->OutBuf;
|
||||
LFlags = This->Termio.c_lflag & (ECHOK | ECHOE);
|
||||
|
||||
if((EChar >= TtyFunKeyMin) && (EChar < TtyFunKeyMax)) {
|
||||
// A special function key was pressed, buffer it, don't echo, and activate.
|
||||
// Process and buffer the character. May produce multiple characters.
|
||||
NumProc = IIO_EchoOne(filp, EChar, FALSE); // Don't echo this character
|
||||
EChar = CHAR_LINEFEED; // Every line must end with '\n' (legacy)
|
||||
}
|
||||
// Process and buffer the character. May produce multiple characters.
|
||||
NumProc = IIO_EchoOne(filp, EChar, EchoIsOK);
|
||||
|
||||
// At this point, the character(s) to write are in OutBuf
|
||||
// First, linearize the buffer
|
||||
NumWritten = OutBuf->Copy(OutBuf, gMD->UString, UNICODE_STRING_MAX-1);
|
||||
gMD->UString[NumWritten] = 0; // Ensure that the buffer is terminated
|
||||
|
||||
if((EChar == IIO_ECHO_KILL) && (LFlags & ECHOE) && EchoIsOK) {
|
||||
// Position the cursor to the start of input.
|
||||
(void)IIO_SetCursorPosition(filp, &This->InitialXY);
|
||||
}
|
||||
// Output the buffer
|
||||
if(filp->f_iflags & _S_IWTTY) {
|
||||
// Output device expects wide characters, Output what we have
|
||||
NumWritten = filp->f_ops->fo_write(filp, NULL, NumWritten, gMD->UString);
|
||||
}
|
||||
else {
|
||||
// Output device expects narrow characters, convert to MBCS
|
||||
MbcsPtr = (char *)gMD->UString2;
|
||||
// Determine the needed space
|
||||
NumProc = (ssize_t)EstimateWtoM((const wchar_t *)gMD->UString, UNICODE_STRING_MAX * sizeof(wchar_t), NULL);
|
||||
|
||||
// Now translate this into MBCS in Buffer
|
||||
NumWritten = wcstombs(MbcsPtr, (const wchar_t *)gMD->UString, NumProc);
|
||||
MbcsPtr[NumWritten] = 0; // Ensure the buffer is terminated
|
||||
|
||||
// Send the MBCS buffer to Output
|
||||
NumWritten = filp->f_ops->fo_write(filp, NULL, NumWritten, MbcsPtr);
|
||||
}
|
||||
// Consume the echoed characters
|
||||
(void)OutBuf->Flush(OutBuf, NumWritten);
|
||||
|
||||
if(EChar == IIO_ECHO_KILL) {
|
||||
if(LFlags == ECHOK) {
|
||||
NumWritten = IIO_WriteOne(filp, OutBuf, CHAR_LINEFEED);
|
||||
}
|
||||
else if((LFlags & ECHOE) && EchoIsOK) {
|
||||
// Position the cursor to the start of input.
|
||||
(void)IIO_SetCursorPosition(filp, &This->InitialXY);
|
||||
}
|
||||
NumWritten = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
return NumWritten;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
FifoDelete(cFIFO *Member)
|
||||
{
|
||||
if(Member != NULL) {
|
||||
Member->Delete(Member);
|
||||
}
|
||||
}
|
||||
|
||||
/** Destructor for an IIO instance.
|
||||
|
||||
Releases all resources used by a particular IIO instance.
|
||||
**/
|
||||
static
|
||||
void
|
||||
EFIAPI
|
||||
IIO_Delete(
|
||||
cIIO *Self
|
||||
)
|
||||
{
|
||||
if(Self != NULL) {
|
||||
FifoDelete(Self->ErrBuf);
|
||||
FifoDelete(Self->OutBuf);
|
||||
FifoDelete(Self->InBuf);
|
||||
if(Self->AttrBuf != NULL) {
|
||||
FreePool(Self->AttrBuf);
|
||||
}
|
||||
FreePool(Self);
|
||||
}
|
||||
}
|
||||
|
||||
/** Constructor for new IIO instances.
|
||||
|
||||
@return Returns NULL or a pointer to a new IIO instance.
|
||||
**/
|
||||
cIIO *
|
||||
EFIAPI
|
||||
New_cIIO(void)
|
||||
{
|
||||
cIIO *IIO;
|
||||
cc_t *TempBuf;
|
||||
int i;
|
||||
|
||||
IIO = (cIIO *)AllocateZeroPool(sizeof(cIIO));
|
||||
if(IIO != NULL) {
|
||||
IIO->InBuf = New_cFIFO(MAX_INPUT, sizeof(wchar_t));
|
||||
IIO->OutBuf = New_cFIFO(MAX_OUTPUT, sizeof(wchar_t));
|
||||
IIO->ErrBuf = New_cFIFO(MAX_OUTPUT, sizeof(wchar_t));
|
||||
IIO->AttrBuf = (UINT8 *)AllocateZeroPool(MAX_OUTPUT);
|
||||
|
||||
if((IIO->InBuf == NULL) || (IIO->OutBuf == NULL) ||
|
||||
(IIO->ErrBuf == NULL) || (IIO->AttrBuf == NULL))
|
||||
{
|
||||
IIO_Delete(IIO);
|
||||
IIO = NULL;
|
||||
}
|
||||
else {
|
||||
IIO->Delete = IIO_Delete;
|
||||
IIO->Read = IIO_Read;
|
||||
IIO->Write = IIO_Write;
|
||||
IIO->Echo = IIO_Echo;
|
||||
}
|
||||
// Initialize Termio member
|
||||
TempBuf = &IIO->Termio.c_cc[0];
|
||||
TempBuf[0] = 8; // Default length for TABs
|
||||
for(i=1; i < NCCS; ++i) {
|
||||
TempBuf[i] = _POSIX_VDISABLE;
|
||||
}
|
||||
TempBuf[VMIN] = 0;
|
||||
TempBuf[VTIME] = 0;
|
||||
IIO->Termio.c_ispeed = B115200;
|
||||
IIO->Termio.c_ospeed = B115200;
|
||||
IIO->Termio.c_iflag = ICRNL;
|
||||
IIO->Termio.c_oflag = OPOST | ONLCR | ONOCR | ONLRET;
|
||||
IIO->Termio.c_cflag = 0;
|
||||
IIO->Termio.c_lflag = ECHO | ECHONL;
|
||||
}
|
||||
return IIO;
|
||||
}
|
51
StdLib/LibC/Uefi/InteractiveIO/IIO.inf
Normal file
51
StdLib/LibC/Uefi/InteractiveIO/IIO.inf
Normal file
@@ -0,0 +1,51 @@
|
||||
## @file
|
||||
# Interactive I/O Library.
|
||||
#
|
||||
# Copyright (c) 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 which accompanies this
|
||||
# distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = LibIIO
|
||||
FILE_GUID = c1e9fffb-5557-4cb5-a5f5-1fbd902a74ed
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = LibIIO
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
IIO.c
|
||||
NonCanonRead.c
|
||||
CanonRead.c
|
||||
TerminalFunctions.c
|
||||
IIOutilities.c
|
||||
IIOwrite.c
|
||||
IIOecho.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
StdLib/StdLib.dec
|
||||
StdLibPrivateInternalFiles/DoNotUse.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
LibC
|
||||
LibWchar
|
||||
LibContainer
|
||||
|
||||
[Protocols]
|
||||
gEfiSimpleTextInProtocolGuid ## CONSUMES
|
||||
gEfiSimpleTextOutProtocolGuid ## CONSUMES
|
141
StdLib/LibC/Uefi/InteractiveIO/IIOecho.c
Normal file
141
StdLib/LibC/Uefi/InteractiveIO/IIOecho.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/** @file
|
||||
Echo characters to an Interactive I/O Output device.
|
||||
|
||||
The functions assume that isatty() is TRUE at the time they are called.
|
||||
Since the UEFI console is a WIDE character device, these functions do all
|
||||
processing using wide characters.
|
||||
|
||||
It is the responsibility of the caller, or higher level function, to perform
|
||||
any necessary translation between wide and narrow characters.
|
||||
|
||||
Copyright (c) 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 which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/termios.h>
|
||||
#include <Device/IIO.h>
|
||||
#include "IIOutilities.h"
|
||||
#include "IIOechoCtrl.h"
|
||||
|
||||
/** Echo one character to an IIO file.
|
||||
|
||||
If character InCh is a special "echo control" character, process it and output
|
||||
the resultant character(s), if any. Otherwise pass the character on to the
|
||||
IIO_WriteOne() function which performs generic output processing, if needed.
|
||||
|
||||
@param[in] filp Pointer to an open IIO file's file descriptor structure.
|
||||
@param[in] InCh The wide character to be echoed.
|
||||
@param[in] EchoIsOK A flag indicating whether echoing is appropriate for this
|
||||
device or not.
|
||||
|
||||
@retval -1 The filp argument does not refer to an IIO device.
|
||||
Global value errno is set to EINVAL.
|
||||
@retval >=0 The number of characters actually output.
|
||||
|
||||
@sa IIO_WriteOne
|
||||
**/
|
||||
ssize_t
|
||||
IIO_EchoOne (
|
||||
struct __filedes *filp,
|
||||
wchar_t InCh,
|
||||
BOOLEAN EchoIsOK
|
||||
)
|
||||
{
|
||||
cIIO *This;
|
||||
cFIFO *OutBuf;
|
||||
cFIFO *InBuf;
|
||||
UINT8 *AttrBuf;
|
||||
ssize_t NumEcho;
|
||||
tcflag_t LFlags;
|
||||
UINT32 AttrDex;
|
||||
int i;
|
||||
|
||||
NumEcho = -1;
|
||||
This = filp->devdata;
|
||||
|
||||
if(This != NULL) {
|
||||
LFlags = This->Termio.c_lflag;
|
||||
OutBuf = This->OutBuf;
|
||||
InBuf = This->InBuf;
|
||||
AttrBuf = This->AttrBuf;
|
||||
AttrDex = InBuf->GetWDex(InBuf);
|
||||
|
||||
switch(InCh) {
|
||||
case IIO_ECHO_DISCARD:
|
||||
// Do not buffer or otherwise process
|
||||
NumEcho = 0;
|
||||
break;
|
||||
|
||||
case IIO_ECHO_ERASE:
|
||||
// Delete last character from InBuf
|
||||
if(!InBuf->IsEmpty(InBuf)) {
|
||||
(void)InBuf->Truncate(InBuf);
|
||||
|
||||
// Erase screen character(s) based on Attrib value
|
||||
if(LFlags & ECHO) {
|
||||
AttrDex = (UINT32)ModuloDecrement(AttrDex, InBuf->NumElements);
|
||||
NumEcho = AttrBuf[AttrDex];
|
||||
for(i = 0; i < NumEcho; ++i) {
|
||||
(void)IIO_WriteOne(filp, OutBuf, CHAR_BACKSPACE);
|
||||
}
|
||||
if(LFlags & ECHOE) {
|
||||
for(i = 0; i < NumEcho; ++i) {
|
||||
(void)IIO_WriteOne(filp, OutBuf, L' ');
|
||||
}
|
||||
for(i = 0; i < NumEcho; ++i) {
|
||||
(void)IIO_WriteOne(filp, OutBuf, CHAR_BACKSPACE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
NumEcho = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IIO_ECHO_KILL:
|
||||
// Flush contents of InBuf and OutBuf
|
||||
InBuf->Flush(InBuf, (size_t)-1);
|
||||
OutBuf->Flush(OutBuf, (size_t)-1);
|
||||
|
||||
// Erase characters from screen.
|
||||
if(LFlags & ECHOE) {
|
||||
NumEcho = IIO_CursorDelta(This, &This->InitialXY, &This->CurrentXY);
|
||||
for(i = 0; i < NumEcho; ++i) {
|
||||
(void)IIO_WriteOne(filp, OutBuf, L' ');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Add character to input buffer
|
||||
(void)InBuf->Write(InBuf, &InCh, 1);
|
||||
|
||||
NumEcho = 0; // In case echoing is not enabled or OK
|
||||
// If echoing is OK and enabled, "echo" character using IIO_WriteOne
|
||||
if( EchoIsOK &&
|
||||
( (LFlags & ECHO) ||
|
||||
((LFlags & ECHONL) && (InCh == CHAR_LINEFEED))))
|
||||
{
|
||||
NumEcho = IIO_WriteOne(filp, OutBuf, InCh);
|
||||
}
|
||||
AttrBuf[AttrDex] = (UINT8)NumEcho;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errno = EINVAL;
|
||||
}
|
||||
return NumEcho;
|
||||
}
|
33
StdLib/LibC/Uefi/InteractiveIO/IIOechoCtrl.h
Normal file
33
StdLib/LibC/Uefi/InteractiveIO/IIOechoCtrl.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/** @file
|
||||
Constants and declarations for the Echo function.
|
||||
|
||||
Copyright (c) 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 which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#ifndef _IIO_ECHO_CTRL_H
|
||||
#define _IIO_ECHO_CTRL_H
|
||||
#include <sys/termios.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* These constants are assigned values within the Unicode Private Use range.
|
||||
The value of IIO_ECHO_MIN must be adjusted to ensure that IIO_ECHO_MAX
|
||||
never exceeds the value of 0xF900.
|
||||
*/
|
||||
typedef enum {
|
||||
IIO_ECHO_MIN = (TtyFunKeyMin - 3),
|
||||
IIO_ECHO_DISCARD = IIO_ECHO_MIN, // Ignore this character completely
|
||||
IIO_ECHO_ERASE, // Erase previous character
|
||||
IIO_ECHO_KILL, // Kill the entire line
|
||||
IIO_ECHO_MAX
|
||||
} IioEchoCtrl;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _IIO_ECHO_CTRL_H */
|
288
StdLib/LibC/Uefi/InteractiveIO/IIOutilities.c
Normal file
288
StdLib/LibC/Uefi/InteractiveIO/IIOutilities.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/** @file
|
||||
Utilities for Interactive I/O Functions.
|
||||
|
||||
The functions assume that isatty() is TRUE at the time they are called.
|
||||
|
||||
Copyright (c) 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 which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
#include <Protocol/SimpleTextOut.h>
|
||||
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <sys/termios.h>
|
||||
#include <Device/IIO.h>
|
||||
#include <MainData.h>
|
||||
#include "IIOutilities.h"
|
||||
|
||||
/** Get the low-level UEFI protocol associated with an open file.
|
||||
|
||||
@param[in] fd File descriptor for an open file.
|
||||
@param[out] filp NULL, or a pointer to where a pointer to the file's
|
||||
file descriptor structure is to be stored.
|
||||
|
||||
@return Returns NULL if fd is not a valid file descriptor, otherwise
|
||||
a pointer to the file's associated UEFI protocol is returned.
|
||||
**/
|
||||
void *
|
||||
EFIAPI
|
||||
IIO_GetDeviceProto (
|
||||
int fd,
|
||||
struct __filedes **filp
|
||||
)
|
||||
{
|
||||
void *Proto;
|
||||
ConInstance *Stream;
|
||||
struct __filedes *pfil;
|
||||
|
||||
Proto = NULL;
|
||||
if(ValidateFD( fd, VALID_OPEN)) {
|
||||
pfil = &gMD->fdarray[fd];
|
||||
Stream = BASE_CR(pfil->f_ops, ConInstance, Abstraction);
|
||||
Proto = (void *)Stream->Dev;
|
||||
if(filp != NULL) {
|
||||
*filp = pfil;
|
||||
}
|
||||
}
|
||||
return Proto;
|
||||
}
|
||||
|
||||
/** Get a character either from the input buffer or from hardware.
|
||||
|
||||
@param[in] filp Pointer to a file descriptor structure.
|
||||
@param[in] First Set to TRUE to identify the initial read.
|
||||
|
||||
@return Returns a character read from either the input buffer
|
||||
or from the open file (device) identified by filp.
|
||||
A return value of WEOF indicates an error has occurred.
|
||||
**/
|
||||
wint_t
|
||||
EFIAPI
|
||||
IIO_GetInChar (
|
||||
struct __filedes *filp,
|
||||
BOOLEAN First
|
||||
)
|
||||
{
|
||||
cIIO *This;
|
||||
cFIFO *InBuf;
|
||||
EFI_STATUS Status;
|
||||
ssize_t NumRead;
|
||||
wint_t RetVal;
|
||||
wchar_t InChar;
|
||||
|
||||
static size_t BufCnt;
|
||||
|
||||
This = filp->devdata;
|
||||
InBuf = This->InBuf;
|
||||
|
||||
NumRead = -1;
|
||||
InChar = 0;
|
||||
if(First) {
|
||||
BufCnt = InBuf->Count(InBuf, AsElements);
|
||||
}
|
||||
if(BufCnt > 0) {
|
||||
Status = InBuf->Read(InBuf, &InChar, 1);
|
||||
--BufCnt;
|
||||
NumRead = 1;
|
||||
}
|
||||
else {
|
||||
NumRead = filp->f_ops->fo_read(filp, &filp->f_offset, sizeof(wchar_t), &InChar);
|
||||
}
|
||||
if(NumRead <= 0) {
|
||||
RetVal = WEOF;
|
||||
}
|
||||
else {
|
||||
RetVal = (wint_t)InChar;
|
||||
}
|
||||
return InChar;
|
||||
}
|
||||
|
||||
/** Get the current cursor position.
|
||||
|
||||
@param[in] fd File descriptor for an open file.
|
||||
@param[out] Column Pointer to where the current cursor column is to be stored.
|
||||
@param[out] Row Pointer to where the current cursor row is to be stored.
|
||||
|
||||
@retval -1 fd is not an IIO output device.
|
||||
@retval 0 Cursor position retrieved, Cursor is Not Visible.
|
||||
@retval 1 Cursor position retrieved, Cursor is Visible.
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
IIO_GetCursorPosition (
|
||||
int fd,
|
||||
UINT32 *Column,
|
||||
UINT32 *Row
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
|
||||
struct __filedes *pStdOut;
|
||||
int RetVal;
|
||||
|
||||
RetVal = -1;
|
||||
|
||||
Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(fd, &pStdOut);
|
||||
if(Proto != NULL) {
|
||||
if(((pStdOut->f_iflags & _S_ITTY) != 0) && // file is a TTY
|
||||
((pStdOut->Oflags & O_ACCMODE) != 0)) // and it is open for output
|
||||
{
|
||||
// fd is for a TTY or "Interactive IO" device
|
||||
*Column = Proto->Mode->CursorColumn;
|
||||
*Row = Proto->Mode->CursorRow;
|
||||
if(Proto->Mode->CursorVisible) {
|
||||
RetVal = 1;
|
||||
}
|
||||
else {
|
||||
RetVal = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/** Set the cursor position.
|
||||
|
||||
@param[in] filp Pointer to the output device's file descriptor structure.
|
||||
@param[in] StartXY Pointer to a cursor coordinate (XY) structure indicating
|
||||
the desired coordinate to move the cursor to.
|
||||
|
||||
@retval -1 fd is not an IIO output device
|
||||
@retval 0 Cursor position set successfully.
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
IIO_SetCursorPosition (
|
||||
struct __filedes *filp,
|
||||
CURSOR_XY *CursorXY
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
|
||||
cIIO *This;
|
||||
EFI_STATUS Status;
|
||||
int RetVal;
|
||||
|
||||
RetVal = -1;
|
||||
|
||||
This = filp->devdata;
|
||||
Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(filp->MyFD, NULL);
|
||||
if(Proto != NULL) {
|
||||
if(((filp->f_iflags & _S_ITTY) != 0) && // file is a TTY
|
||||
((filp->Oflags & O_ACCMODE) != 0)) // and it is open for output
|
||||
{
|
||||
// fd is for a TTY or "Interactive IO" device
|
||||
Status = Proto->SetCursorPosition(Proto, CursorXY->Column, CursorXY->Row);
|
||||
if(Status == EFI_SUCCESS) {
|
||||
This->CurrentXY.Column = CursorXY->Column;
|
||||
This->CurrentXY.Row = CursorXY->Row;
|
||||
RetVal = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/** Get Output screen size and mode.
|
||||
|
||||
@param[in] fd File descriptor of the output device.
|
||||
@param[out] Col Pointer to where to store the MAX Column, or NULL.
|
||||
@param[out] Row Pointer to where to store the MAX Row, or NULL.
|
||||
|
||||
@retval <0 An error occurred. The reason is in errno and EFIerrno.
|
||||
* EIO UEFI QueryMode failed
|
||||
* ENOTTY fd does not refer to an interactive output device
|
||||
@retval >=0 Current output mode
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
IIO_GetOutputSize (
|
||||
int fd,
|
||||
UINTN *Col,
|
||||
UINTN *Row
|
||||
)
|
||||
{
|
||||
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
|
||||
struct __filedes *pStdOut;
|
||||
EFI_STATUS Status;
|
||||
UINTN TempCol;
|
||||
UINTN TempRow;
|
||||
UINTN TempMode;
|
||||
int RetVal;
|
||||
|
||||
RetVal = -1;
|
||||
|
||||
Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(fd, &pStdOut);
|
||||
if(Proto != NULL) {
|
||||
if(((pStdOut->f_iflags & _S_ITTY) != 0) && // file is a TTY
|
||||
((pStdOut->Oflags & O_ACCMODE) != 0)) // and it is open for output
|
||||
{
|
||||
// fd is for a TTY or "Interactive IO" device
|
||||
TempMode = Proto->Mode->Mode;
|
||||
Status = Proto->QueryMode(Proto, TempMode, &TempCol, &TempRow);
|
||||
if(EFI_ERROR(Status)) {
|
||||
EFIerrno = Status;
|
||||
errno = EIO;
|
||||
}
|
||||
else {
|
||||
*Col = TempCol;
|
||||
*Row = TempRow;
|
||||
RetVal = (int)TempMode;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errno = ENOTTY;
|
||||
}
|
||||
}
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/** Calculate the number of character positions between two X/Y coordinate pairs.
|
||||
|
||||
Using the current output device characteristics, calculate the number of
|
||||
characters between two coordinates. It is assumed that EndXY points to
|
||||
an output location that occurs after StartXY.
|
||||
|
||||
RowDelta is the computed difference between the ending and starting rows.
|
||||
If RowDelta < 0, then EndXY is NOT after StartXY, so assert.
|
||||
|
||||
ColumnDelta is the computed number of character positions (columns) between
|
||||
the starting position and the ending position. If ColumnDelta is < 0,
|
||||
then EndXY is NOT after StartXY, so assert.
|
||||
|
||||
@param[in] This Pointer to the IIO instance to be examined.
|
||||
@param[in] StartXY Pointer to the starting coordinate pair.
|
||||
@param[in] EndXY Pointer to the ending coordinate pair.
|
||||
|
||||
@return Returns the difference between the starting and ending coordinates.
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
IIO_CursorDelta (
|
||||
cIIO *This,
|
||||
CURSOR_XY *StartXY,
|
||||
CURSOR_XY *EndXY
|
||||
)
|
||||
{
|
||||
INT32 ColumnDelta;
|
||||
INT32 RowDelta;
|
||||
|
||||
RowDelta = (int)EndXY->Row - (int)StartXY->Row;
|
||||
|
||||
assert(RowDelta >= 0); // assert if EndXY is NOT after StartXY
|
||||
|
||||
ColumnDelta = (INT32)((This->MaxColumn * RowDelta) + EndXY->Column);
|
||||
ColumnDelta -= (INT32)StartXY->Column;
|
||||
|
||||
assert(ColumnDelta >= 0); // assert if EndXY is NOT after StartXY
|
||||
|
||||
return (UINT32)ColumnDelta;
|
||||
}
|
129
StdLib/LibC/Uefi/InteractiveIO/IIOutilities.h
Normal file
129
StdLib/LibC/Uefi/InteractiveIO/IIOutilities.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/** @file
|
||||
Utilities for Interactive I/O Functions.
|
||||
|
||||
The functions assume that isatty() is TRUE at the time they are called.
|
||||
|
||||
Copyright (c) 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 which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#ifndef _IIO_UTILITIES_H
|
||||
#define _IIO_UTILITIES_H
|
||||
|
||||
#include <sys/EfiSysCall.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/** Get the low-level UEFI protocol associated with an open file.
|
||||
|
||||
@param[in] fd File descriptor for an open file.
|
||||
@param[out] filp NULL, or a pointer to where a pointer to the file's
|
||||
file descriptor structure is to be stored.
|
||||
|
||||
@return Returns NULL if fd is not a valid file descriptor, otherwise
|
||||
a pointer to the file's associated UEFI protocol is returned.
|
||||
**/
|
||||
void *
|
||||
EFIAPI
|
||||
IIO_GetDeviceProto (
|
||||
int fd,
|
||||
struct __filedes **filp // Optional - filp == NULL if unused
|
||||
);
|
||||
|
||||
/** Get a character either from the input buffer or from hardware.
|
||||
|
||||
@param[in] filp Pointer to a file descriptor structure.
|
||||
@param[in] First Set to TRUE to identify the initial read.
|
||||
|
||||
@return Returns a character read from either the input buffer
|
||||
or from the open file (device) identified by filp.
|
||||
A return value of WEOF indicates an error has occurred.
|
||||
**/
|
||||
wint_t
|
||||
EFIAPI
|
||||
IIO_GetInChar (
|
||||
struct __filedes *filp,
|
||||
BOOLEAN First
|
||||
);
|
||||
|
||||
/** Get the current cursor position.
|
||||
|
||||
@param[in] fd File descriptor for an open file.
|
||||
@param[out] Column Pointer to where the current cursor column is to be stored.
|
||||
@param[out] Row Pointer to where the current cursor row is to be stored.
|
||||
|
||||
@retval -1 fd is not an IIO output device.
|
||||
@retval 0 Cursor position retrieved, Cursor is Not Visible.
|
||||
@retval 1 Cursor position retrieved, Cursor is Visible.
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
IIO_GetCursorPosition (
|
||||
int fd,
|
||||
UINT32 *Column,
|
||||
UINT32 *Row
|
||||
);
|
||||
|
||||
/** Set the cursor position.
|
||||
|
||||
@param[in] filp Pointer to the output device's file descriptor structure.
|
||||
@param[in] StartXY Pointer to a cursor coordinate (XY) structure indicating
|
||||
the desired coordinate to move the cursor to.
|
||||
|
||||
@retval -1 fd is not an IIO output device
|
||||
@retval 0 Cursor position set successfully.
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
IIO_SetCursorPosition (
|
||||
struct __filedes *filp,
|
||||
CURSOR_XY *StartXY
|
||||
);
|
||||
|
||||
/** Get Output screen size and mode.
|
||||
|
||||
@param[in] fd File descriptor of the output device.
|
||||
@param[out] Col Pointer to where to store the MAX Column, or NULL.
|
||||
@param[out] Row Pointer to where to store the MAX Row, or NULL.
|
||||
|
||||
@retval <0 An error occurred. The reason is in errno and EFIerrno.
|
||||
* EIO UEFI QueryMode failed
|
||||
* ENOTTY fd does not refer to an interactive output device
|
||||
@retval >=0 Current output mode
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
IIO_GetOutputSize (
|
||||
int fd,
|
||||
UINTN *Col,
|
||||
UINTN *Row
|
||||
);
|
||||
|
||||
/** Calculate the number of character positions between two X/Y coordinate pairs.
|
||||
|
||||
Using the current output device characteristics, calculate the number of
|
||||
characters between two coordinates.
|
||||
|
||||
@param[in] This Pointer to the IIO instance to be examined.
|
||||
@param[in] StartXY Pointer to the starting coordinate pair.
|
||||
@param[in] EndXY Pointer to the ending coordinate pair.
|
||||
|
||||
@return Returns the difference between the starting and ending coordinates.
|
||||
The return value is positive if the coordinates contained in EndXY
|
||||
are larger than StartXY, otherwise the return value is negative.
|
||||
**/
|
||||
int
|
||||
EFIAPI
|
||||
IIO_CursorDelta (
|
||||
cIIO *This,
|
||||
CURSOR_XY *StartXY,
|
||||
CURSOR_XY *EndXY
|
||||
);
|
||||
|
||||
__END_DECLS
|
||||
#endif /* _IIO_UTILITIES_H */
|
210
StdLib/LibC/Uefi/InteractiveIO/IIOwrite.c
Normal file
210
StdLib/LibC/Uefi/InteractiveIO/IIOwrite.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/** @file
|
||||
Write to an Interactive I/O Output device.
|
||||
|
||||
The functions assume that isatty() is TRUE at the time they are called.
|
||||
Since the UEFI console is a WIDE character device, these functions do all
|
||||
processing using wide characters.
|
||||
|
||||
It is the responsibility of the caller, or higher level function, to perform
|
||||
any necessary translation between wide and narrow characters.
|
||||
|
||||
Copyright (c) 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 which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/termios.h>
|
||||
#include <Device/IIO.h>
|
||||
|
||||
static wchar_t Spaces[] = L" "; // Spaces for expanding TABs
|
||||
|
||||
#define MAX_TAB_WIDTH ((int)(sizeof(Spaces) / sizeof(wchar_t)) - 1)
|
||||
|
||||
#define MAX_EXPANSION 3
|
||||
|
||||
/** Process and buffer one character for output.
|
||||
|
||||
@param[in] filp Pointer to a file descriptor structure.
|
||||
@param[out] OBuf Pointer to the Output Buffer FIFO.
|
||||
@param[in] InCh The wide character to process.
|
||||
|
||||
@retval <0 An error occurred. Reason is in errno.
|
||||
* EINVAL The pointer to the IIO object is NULL.
|
||||
* ENOSPC The OBuf FIFO is full.
|
||||
|
||||
@retval 0 A character was input but not placed in the output buffer.
|
||||
|
||||
@retval >0 The number of characters buffered. Normally 1, or 2.
|
||||
If a character is discarded because of flag settings, a
|
||||
1 will be returned.
|
||||
**/
|
||||
ssize_t
|
||||
IIO_WriteOne(struct __filedes *filp, cFIFO *OBuf, wchar_t InCh)
|
||||
{
|
||||
cIIO *This;
|
||||
struct termios *Termio;
|
||||
tcflag_t OFlag;
|
||||
ssize_t RetVal;
|
||||
wchar_t wc[MAX_EXPANSION]; // Sub-buffer for conversions
|
||||
wchar_t *wcb; // Pointer to either wc or spaces
|
||||
int numW = 0; // Wide characters placed in OBuf
|
||||
INT32 TabWidth; // Each TAB expands into this number of spaces
|
||||
UINT32 CurColumn; // Current cursor column on the screen
|
||||
UINT32 CurRow; // Current cursor row on the screen
|
||||
UINT32 PrevColumn; // Previous column. Used to detect wrapping.
|
||||
UINT32 AdjColumn; // Current cursor column on the screen
|
||||
UINT32 AdjRow; // Current cursor row on the screen
|
||||
|
||||
RetVal = -1;
|
||||
wcb = wc;
|
||||
This = filp->devdata;
|
||||
if((This != NULL) && (OBuf->FreeSpace(OBuf, AsElements) >= MAX_EXPANSION)) {
|
||||
Termio = &This->Termio;
|
||||
OFlag = Termio->c_oflag;
|
||||
TabWidth = (INT32)This->Termio.c_cc[VTABLEN];
|
||||
if(TabWidth > MAX_TAB_WIDTH) {
|
||||
TabWidth = MAX_TAB_WIDTH;
|
||||
}
|
||||
CurColumn = This->CurrentXY.Column;
|
||||
CurRow = This->CurrentXY.Row;
|
||||
|
||||
numW = 1; // The majority of characters buffer one character
|
||||
AdjRow = 0; // Most characters just cause horizontal movement
|
||||
AdjColumn = 0;
|
||||
if(OFlag & OPOST) {
|
||||
/* Perform output processing */
|
||||
switch(InCh) {
|
||||
case CHAR_TAB: //{{
|
||||
if(OFlag & OXTABS) {
|
||||
if(TabWidth > 0) {
|
||||
int SpaceIndex;
|
||||
|
||||
SpaceIndex = CurColumn % TabWidth; // Number of spaces after a Tab Stop
|
||||
numW = TabWidth - SpaceIndex; // Number of spaces to the next Tab Stop
|
||||
SpaceIndex = MAX_TAB_WIDTH - numW; // Index into the Spaces array
|
||||
wcb = &Spaces[SpaceIndex]; // Point to the appropriate number of spaces
|
||||
}
|
||||
else {
|
||||
wc[0] = L' ';
|
||||
}
|
||||
AdjColumn = numW;
|
||||
}
|
||||
else {
|
||||
wc[0] = InCh; // Send the TAB itself - assumes that it does not move cursor.
|
||||
}
|
||||
break; //}}
|
||||
|
||||
case CHAR_CARRIAGE_RETURN: //{{
|
||||
if((OFlag & OCRNL) == 0) {
|
||||
if((OFlag & ONLRET) == 0) {
|
||||
numW = 0; /* Discard the CR */
|
||||
// Cursor doesn't move
|
||||
}
|
||||
else {
|
||||
wc[0] = CHAR_CARRIAGE_RETURN;
|
||||
CurColumn = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
InCh = CHAR_LINEFEED;
|
||||
} //}}
|
||||
// Fall through to the NL case
|
||||
case CHAR_LINEFEED: //{{
|
||||
if(OFlag & ONLCR) {
|
||||
wc[0] = CHAR_CARRIAGE_RETURN;
|
||||
wc[1] = CHAR_LINEFEED;
|
||||
numW = 2;
|
||||
CurColumn = 0;
|
||||
}
|
||||
AdjRow = 1;
|
||||
break; //}}
|
||||
|
||||
case CHAR_BACKSPACE: //{{
|
||||
if(CurColumn > 0) {
|
||||
wc[0] = CHAR_BACKSPACE;
|
||||
CurColumn = (UINT32)ModuloDecrement(CurColumn, (UINT32)This->MaxColumn);
|
||||
}
|
||||
else {
|
||||
numW = 0; // Discard the backspace if in column 0
|
||||
}
|
||||
break; //}}
|
||||
|
||||
case CHAR_EOT: //{{
|
||||
if(OFlag & ONOEOT) {
|
||||
numW = 0; // Discard the EOT character
|
||||
// Cursor doesn't move
|
||||
break;
|
||||
} //}}
|
||||
// Fall through to default in order to potentially output "^D"
|
||||
default: //{{
|
||||
if((InCh >= 0) && (InCh < L' ')) {
|
||||
// InCh contains a control character
|
||||
if(OFlag & OCTRL) {
|
||||
wc[1] = InCh + L'@';
|
||||
wc[0] = L'^';
|
||||
numW = 2;
|
||||
AdjColumn = 2;
|
||||
}
|
||||
else {
|
||||
numW = 0; // Discard. Not a UEFI supported control character.
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Regular printing character
|
||||
wc[0] = InCh;
|
||||
AdjColumn = 1;
|
||||
}
|
||||
break; //}}
|
||||
}
|
||||
if(numW < MAX_EXPANSION) {
|
||||
wc[numW] = 0; // Terminate the sub-buffer
|
||||
}
|
||||
if(AdjColumn != 0) {
|
||||
// Adjust the cursor position
|
||||
PrevColumn = CurColumn;
|
||||
CurColumn = ModuloAdd(PrevColumn, AdjColumn, (UINT32)This->MaxColumn);
|
||||
if(CurColumn < PrevColumn) {
|
||||
// We must have wrapped, so we are on the next Row
|
||||
++CurRow;
|
||||
if(CurRow >= This->MaxRow) {
|
||||
// The screen has scrolled so need to adjust Initial location.
|
||||
--This->InitialXY.Row; // Initial row has moved up one
|
||||
CurRow = (UINT32)(This->MaxRow - 1); // We stay on the bottom row
|
||||
}
|
||||
}
|
||||
}
|
||||
This->CurrentXY.Column = CurColumn;
|
||||
This->CurrentXY.Row = CurRow;
|
||||
}
|
||||
else {
|
||||
// Output processing disabled -- RAW output mode
|
||||
wc[0] = InCh;
|
||||
wc[1] = 0;
|
||||
}
|
||||
// Put the character(s) into the output buffer
|
||||
if(numW > 0) {
|
||||
(void)OBuf->Write(OBuf, (const void *)wcb, (size_t)numW);
|
||||
}
|
||||
RetVal = numW;
|
||||
}
|
||||
else {
|
||||
if(This == NULL) {
|
||||
errno = EINVAL;
|
||||
}
|
||||
else {
|
||||
errno = ENOSPC;
|
||||
}
|
||||
}
|
||||
return RetVal;
|
||||
}
|
89
StdLib/LibC/Uefi/InteractiveIO/NonCanonRead.c
Normal file
89
StdLib/LibC/Uefi/InteractiveIO/NonCanonRead.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/** @file
|
||||
NonCanonical Interactive Input Function.
|
||||
|
||||
The functions assume that isatty() is TRUE at the time they are called.
|
||||
If _S_IWTTY is set, the device returns WIDE characters.
|
||||
|
||||
Copyright (c) 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 which accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <sys/syslimits.h>
|
||||
#include <sys/termios.h>
|
||||
#include <Device/IIO.h>
|
||||
#include <Containers/Fifo.h>
|
||||
|
||||
/** Perform a noncanonical read of input.
|
||||
|
||||
@param[in] filp Pointer to a file descriptor structure.
|
||||
@param[in] BufferSize Maximum number of bytes to return.
|
||||
|
||||
@retval -1 An error has occurred. Reason in errno.
|
||||
@retval -1 No data returned. None was ready.
|
||||
@retval >0 The number of elements returned
|
||||
**/
|
||||
ssize_t
|
||||
IIO_NonCanonRead (
|
||||
struct __filedes *filp
|
||||
)
|
||||
{
|
||||
cIIO *This;
|
||||
cFIFO *InBuf;
|
||||
struct termios *Termio;
|
||||
EFI_STATUS Status;
|
||||
ssize_t NumRead;
|
||||
cc_t tioMin;
|
||||
cc_t tioTime;
|
||||
UINT32 InputType;
|
||||
wchar_t InChar; // Intermediate character buffer
|
||||
|
||||
NumRead = -1;
|
||||
InChar = 0; // Initialize so compilers don't complain.
|
||||
This = filp->devdata;
|
||||
Termio = &This->Termio;
|
||||
InBuf = This->InBuf;
|
||||
tioMin = Termio->c_cc[VMIN];
|
||||
tioTime = Termio->c_cc[VTIME];
|
||||
|
||||
if(tioMin >= MAX_INPUT) {
|
||||
tioMin = MAX_INPUT;
|
||||
}
|
||||
/* There are four types of processing that may be done, based on
|
||||
the values of tioMin and tioTime.
|
||||
Min Time Type
|
||||
--- ---- ----
|
||||
0 0 0 Return buffer contents or 1 new char
|
||||
0 >0 1 Return 0 or 1 character depending on timeout
|
||||
>0 0 2 Buffer Min chars. Return BufferSize chars.
|
||||
>0 >0 3 Return up to Min chars. Unless the inter-byte timer expires.
|
||||
|
||||
Currently, only type 0 is implemented.
|
||||
*/
|
||||
InputType = 0;
|
||||
if(tioMin != 0) InputType = 2;
|
||||
if(tioTime != 0) ++InputType;
|
||||
//switch(InputType) {
|
||||
// case 0:
|
||||
if(InBuf->IsEmpty(InBuf)) {
|
||||
NumRead = filp->f_ops->fo_read(filp, &filp->f_offset, sizeof(wchar_t), &InChar);
|
||||
if(NumRead > 0) {
|
||||
Status = InBuf->Write(InBuf, &InChar, 1); // Buffer the character
|
||||
}
|
||||
}
|
||||
// break;
|
||||
// case 1:
|
||||
// break;
|
||||
// case 2:
|
||||
// break;
|
||||
// case 3:
|
||||
// break;
|
||||
//}
|
||||
return NumRead;
|
||||
}
|
285
StdLib/LibC/Uefi/InteractiveIO/TerminalFunctions.c
Normal file
285
StdLib/LibC/Uefi/InteractiveIO/TerminalFunctions.c
Normal file
@@ -0,0 +1,285 @@
|
||||
/** @file
|
||||
"Terminal" Control functions for Interactive IO.
|
||||
|
||||
Copyright (c) 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.
|
||||
The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/termios.h>
|
||||
#include <Device/IIO.h>
|
||||
#include <MainData.h>
|
||||
|
||||
/** Get input baud rate.
|
||||
|
||||
Extracts the input baud rate from the termios structure pointed to by the
|
||||
pTermios argument.
|
||||
|
||||
@param[in] pTermios A pointer to the termios structure from which to extract
|
||||
the input baud rate.
|
||||
|
||||
@return The value of the input speed is returned exactly as it is contained
|
||||
in the termios structure, without interpretation.
|
||||
**/
|
||||
speed_t
|
||||
cfgetispeed (
|
||||
const struct termios *pTermios
|
||||
)
|
||||
{
|
||||
return pTermios->c_ispeed;
|
||||
}
|
||||
|
||||
/** Get output baud rate.
|
||||
|
||||
Extracts the output baud rate from the termios structure pointed to by the
|
||||
pTermios argument.
|
||||
|
||||
@param[in] pTermios A pointer to the termios structure from which to extract
|
||||
the output baud rate.
|
||||
|
||||
@return The value of the output speed is returned exactly as it is contained
|
||||
in the termios structure, without interpretation.
|
||||
**/
|
||||
speed_t
|
||||
cfgetospeed (
|
||||
const struct termios *pTermios
|
||||
)
|
||||
{
|
||||
return pTermios->c_ospeed;
|
||||
}
|
||||
|
||||
/** Set input baud rate.
|
||||
|
||||
Replaces the input baud rate, in the termios structure pointed to by the
|
||||
pTermios argument, with the value of NewSpeed.
|
||||
|
||||
@param[out] pTermios A pointer to the termios structure into which to set
|
||||
the input baud rate.
|
||||
@param[in] NewSpeed The new input baud rate.
|
||||
|
||||
@retval 0 The operation completed successfully.
|
||||
@retval -1 An error occured and errno is set to indicate the error.
|
||||
* EINVAL - The value of NewSpeed is outside the range of
|
||||
possible speed values as specified in <sys/termios.h>.
|
||||
**/
|
||||
int
|
||||
cfsetispeed (
|
||||
struct termios *pTermios,
|
||||
speed_t NewSpeed
|
||||
)
|
||||
{
|
||||
int RetVal;
|
||||
|
||||
if(NewSpeed < B921600) {
|
||||
pTermios->c_ispeed = NewSpeed;
|
||||
RetVal = 0;
|
||||
}
|
||||
else {
|
||||
RetVal = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/** Set output baud rate.
|
||||
|
||||
Replaces the output baud rate, in the termios structure pointed to by the
|
||||
pTermios argument, with the value of NewSpeed.
|
||||
|
||||
@param[out] pTermios A pointer to the termios structure into which to set
|
||||
the output baud rate.
|
||||
@param[in] NewSpeed The new output baud rate.
|
||||
|
||||
@retval 0 The operation completed successfully.
|
||||
@retval -1 An error occured and errno is set to indicate the error.
|
||||
* EINVAL - The value of NewSpeed is outside the range of
|
||||
possible speed values as specified in <sys/termios.h>.
|
||||
**/
|
||||
int
|
||||
cfsetospeed (
|
||||
struct termios *pTermios,
|
||||
speed_t NewSpeed
|
||||
)
|
||||
{
|
||||
int RetVal;
|
||||
|
||||
if(NewSpeed < B921600) {
|
||||
pTermios->c_ospeed = NewSpeed;
|
||||
RetVal = 0;
|
||||
}
|
||||
else {
|
||||
RetVal = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/** Get the parameters associated with an interactive IO device.
|
||||
|
||||
Get the parameters associated with the device referred to by
|
||||
fd and store them into the termios structure referenced by pTermios.
|
||||
|
||||
@param[in] fd The file descriptor for an open interactive IO device.
|
||||
@param[out] pTermios A pointer to a termios structure into which to store
|
||||
attributes of the interactive IO device.
|
||||
|
||||
@retval 0 The operation completed successfully.
|
||||
@retval -1 An error occured and errno is set to indicate the error.
|
||||
* EBADF - The fd argument is not a valid file descriptor.
|
||||
* ENOTTY - The file associated with fd is not an interactive IO device.
|
||||
**/
|
||||
int
|
||||
tcgetattr (
|
||||
int fd,
|
||||
struct termios *pTermios
|
||||
)
|
||||
{
|
||||
cIIO *IIO;
|
||||
int RetVal;
|
||||
struct __filedes *filp;
|
||||
struct termios *Termio;
|
||||
|
||||
RetVal = 0;
|
||||
if(ValidateFD( fd, VALID_OPEN)) {
|
||||
filp = &gMD->fdarray[fd];
|
||||
|
||||
if((filp->f_iflags & _S_ITTY) != 0) {
|
||||
// fd is for a TTY or "Interactive IO" device
|
||||
IIO = (cIIO *)filp->devdata;
|
||||
Termio = &IIO->Termio;
|
||||
(void)CopyMem((void *)pTermios, (const void *)Termio, sizeof(struct termios));
|
||||
}
|
||||
else {
|
||||
errno = ENOTTY;
|
||||
RetVal = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errno = EBADF;
|
||||
RetVal = -1;
|
||||
}
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/** Set the parameters associated with an interactive IO device.
|
||||
|
||||
Set the parameters associated with the device referred to by
|
||||
fd to the values in the termios structure referenced by pTermios.
|
||||
|
||||
Behavior is modified by the value of the OptAct parameter:
|
||||
* TCSANOW: The change shall occur immediately.
|
||||
* TCSADRAIN: The change shall occur after all output written to fd is
|
||||
transmitted. This action should be used when changing parameters which
|
||||
affect output.
|
||||
* TCSAFLUSH: The change shall occur after all output written to fd is
|
||||
transmitted, and all input so far received but not read shall be
|
||||
discarded before the change is made.
|
||||
|
||||
@param[in] fd The file descriptor for an open interactive IO device.
|
||||
@param[in] OptAct Currently has no effect.
|
||||
@param[in] pTermios A pointer to a termios structure into which to retrieve
|
||||
attributes to set in the interactive IO device.
|
||||
|
||||
@retval 0 The operation completed successfully.
|
||||
@retval -1 An error occured and errno is set to indicate the error.
|
||||
* EBADF - The fd argument is not a valid file descriptor.
|
||||
* ENOTTY - The file associated with fd is not an interactive IO device.
|
||||
**/
|
||||
int
|
||||
tcsetattr (
|
||||
int fd,
|
||||
int OptAct, // Currently ignored
|
||||
const struct termios *pTermios
|
||||
)
|
||||
{
|
||||
cIIO *IIO;
|
||||
int RetVal;
|
||||
struct __filedes *filp;
|
||||
struct termios *Termio;
|
||||
|
||||
RetVal = 0;
|
||||
if(ValidateFD( fd, VALID_OPEN)) {
|
||||
filp = &gMD->fdarray[fd];
|
||||
|
||||
if((filp->f_iflags & _S_ITTY) != 0) {
|
||||
// fd is for a TTY or "Interactive IO" device
|
||||
IIO = (cIIO *)filp->devdata;
|
||||
Termio = &IIO->Termio;
|
||||
(void)CopyMem((void *)Termio, (const void *)pTermios, sizeof(struct termios));
|
||||
}
|
||||
else {
|
||||
errno = ENOTTY;
|
||||
RetVal = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errno = EBADF;
|
||||
RetVal = -1;
|
||||
}
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/** Transmit pending output.
|
||||
|
||||
Function is not yet implemented for UEFI.
|
||||
|
||||
@param[in] fd Ignored
|
||||
|
||||
@retval -1 This function is not yet supported. errno is set to ENOTSUP.
|
||||
**/
|
||||
int
|
||||
tcdrain (int fd)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Suspend or restart the transmission or reception of data.
|
||||
|
||||
This function will suspend or resume transmission or reception of data on
|
||||
the file referred to by fd, depending on the value of Action.
|
||||
|
||||
Function is not yet implemented for UEFI.
|
||||
|
||||
@param[in] fd Ignored
|
||||
@param[in] Action Ignored
|
||||
|
||||
@retval -1 This function is not yet supported. errno is set to ENOTSUP.
|
||||
**/
|
||||
int
|
||||
tcflow (
|
||||
int fd,
|
||||
int Action)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Discard non-transmitted output data, non-read input data, or both.
|
||||
|
||||
Function is not yet implemented for UEFI.
|
||||
|
||||
@param[in] fd Ignored
|
||||
@param[in] QueueSelector Ignored
|
||||
|
||||
@retval -1 This function is not yet supported. errno is set to ENOTSUP.
|
||||
**/
|
||||
int
|
||||
tcflush (
|
||||
int fd,
|
||||
int QueueSelector)
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user