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:
darylm503
2012-12-11 21:19:14 +00:00
parent e575c101d8
commit 6c6c850ad6
23 changed files with 3404 additions and 218 deletions

View 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;
}

View 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;
}

View 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

View 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;
}

View 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 */

View 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;
}

View 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 */

View 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;
}

View 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;
}

View 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;
}