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
		
	
		
			
				
	
	
		
			162 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @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;
 | 
						|
}
 |