X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=StdLib%2FLibC%2FUefi%2FInteractiveIO%2FIIO.c;fp=StdLib%2FLibC%2FUefi%2FInteractiveIO%2FIIO.c;h=0000000000000000000000000000000000000000;hp=547fdb3874f8a08b2f32ef49313ee285aaf104cc;hb=964f432b9b0afe103c41c7613fade3e699118afe;hpb=e2d3a25f1a3135221a9c8061e1b8f90245d727eb diff --git a/StdLib/LibC/Uefi/InteractiveIO/IIO.c b/StdLib/LibC/Uefi/InteractiveIO/IIO.c deleted file mode 100644 index 547fdb3874..0000000000 --- a/StdLib/LibC/Uefi/InteractiveIO/IIO.c +++ /dev/null @@ -1,417 +0,0 @@ -/** @file - Definitions for the Interactive IO library. - - The functions assume that isatty() is TRUE at the time they are called. - - Copyright (c) 2016, Daryl McDaniel. All rights reserved.
- Copyright (c) 2012, Intel Corporation. All rights reserved.
- 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 -#include - -#include - -#include -#include -#include -#include -#include -#include -#include "IIOutilities.h" -#include "IIOechoCtrl.h" - -// Instrumentation used for debugging -#define IIO_C_DEBUG 0 ///< Set to 1 to enable instrumentation, 0 to disable - -#if IIO_C_DEBUG - static volatile size_t IIO_C_WRemainder = 0; ///< Characters in Out buffer after IIO_Write - static volatile size_t IIO_C_RRemainder = 0; ///< Characters in In buffer after IIO_Read - - #define W_INSTRUMENT IIO_C_WRemainder = - #define R_INSTRUMENT IIO_C_RRemainder = -#else // ! IIO_C_DEBUG -- don't instrument code - #define W_INSTRUMENT (void) - #define R_INSTRUMENT (void) -#endif // IIO_C_DEBUG - -/** 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); - } -#if IIO_C_DEBUG - IIO_C_RRemainder = This->InBuf->Count(This->InBuf, AsElements); -#endif // IIO_C_DEBUG - } - return NumRead; -} - -/** Handle write to a Terminal (Interactive) device. - - Processes characters from buffer buf and writes them to the Terminal device - specified by filp. - - The parameter buf points to a MBCS string to be output. This is processed - and buffered one character at a time by IIO_WriteOne() which handles TAB - expansion, NEWLINE to CARRIAGE_RETURN + NEWLINE expansion, as well as - basic line editing functions. The number of characters actually written to - the output device will seldom equal the number of characters consumed from - buf. - - In this implementation, all of the special characters processed by - IIO_WriteOne() are single-byte characters with values less than 128. - (7-bit ASCII or the single-byte UTF-8 characters) - - Every byte that is not one of the recognized special characters is passed, - unchanged, to the Terminal device. - - @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 consumed from buf and sent to the - Terminal 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 NumConsumed; - ssize_t NumProc; - size_t CharLen; - UINTN MaxColumn; - UINTN MaxRow; - wchar_t OutChar[2]; // Just in case we run into a 4-byte MBCS character - int OutMode; - - NumConsumed = -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; - - NumConsumed = 0; - OutChar[0] = (wchar_t)buf[0]; - while((OutChar[0] != 0) && (NumConsumed < N)) { - CharLen = mbrtowc(OutChar, (const char *)&buf[NumConsumed], MB_CUR_MAX, OutState); - if (CharLen < 0) { // Encoding Error - OutChar[0] = BLOCKELEMENT_LIGHT_SHADE; - CharLen = 1; // Consume a byte - (void)mbrtowc(NULL, NULL, 1, OutState); // Re-Initialize the conversion state - } - NumProc = IIO_WriteOne(filp, OutBuf, OutChar[0]); - if(NumProc >= 0) { - // Successfully processed and buffered one character - NumConsumed += CharLen; // Index of start of next character - } - else { - if (errno == ENOSPC) { - // Not enough room in OutBuf to hold a potentially expanded character - break; - } - return -1; // Something corrupted and filp->devdata is now NULL - } - } - // At this point, the characters to write are in OutBuf - // First, linearize the buffer - NumProc = OutBuf->Copy(OutBuf, gMD->UString, UNICODE_STRING_MAX-1); - gMD->UString[NumProc] = 0; // Ensure that the buffer is terminated - - if(filp->f_iflags & _S_IWTTY) { - // Output device expects wide characters, Output what we have - NumProc = filp->f_ops->fo_write(filp, NULL, NumProc, gMD->UString); - - // Consume the output characters - W_INSTRUMENT OutBuf->Flush(OutBuf, NumProc); - } - else { - // Output device expects narrow characters, convert to MBCS - MbcsPtr = (char *)gMD->UString2; - // Determine the needed space. NumProc is the number of bytes needed. - NumProc = (ssize_t)EstimateWtoM((const wchar_t *)gMD->UString, UNICODE_STRING_MAX * sizeof(wchar_t), &CharLen); - - // Now translate this into MBCS in the buffer pointed to by MbcsPtr. - // The returned value, NumProc, is the resulting number of bytes. - NumProc = wcstombs(MbcsPtr, (const wchar_t *)gMD->UString, NumProc); - MbcsPtr[NumProc] = 0; // Ensure the buffer is terminated - - // Send the MBCS buffer to Output - NumProc = filp->f_ops->fo_write(filp, NULL, NumProc, MbcsPtr); - // Mark the Mbcs buffer after the last byte actually written - MbcsPtr[NumProc] = 0; - // Count the CHARACTERS actually sent - CharLen = CountMbcsChars(MbcsPtr); - - // Consume the number of output characters actually sent - W_INSTRUMENT OutBuf->Flush(OutBuf, CharLen); - } - } - else { - if(This == NULL) { - errno = EINVAL; - } - // Otherwise, errno is already set. - } - return NumConsumed; -} - -/** 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; -}