From d7ce700605e1af0e455e31ec11f19ff21d26b525 Mon Sep 17 00:00:00 2001 From: darylm503 Date: Sat, 30 Jul 2011 00:30:44 +0000 Subject: Add Socket Libraries. Add Posix functions for porting compatibility. Fix compliance issues with ISO/IEC 9899:199409 New Functions: setenv(), fparseln(), GetFileNameFromPath(), rename(), realpath(), setprogname(), getprogname(), strlcat(), strlcpy(), strsep(), setitimer(), getitimer(), timegm(), getopt(), basename(), mkstemp(), ffs(), vsnprintf(), snprintf(), getpass(), usleep(), select(), writev(), strcasecmp(), getcwd(), chdir(), tcgetpgrp(), getpgrp(), gettimeofday(), bcopy(), git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12061 6f19259b-4bc3-4df7-8a09-765794883524 --- StdLib/LibC/Uefi/Devices/Console/daConsole.c | 198 +++++++++++++++++---------- 1 file changed, 124 insertions(+), 74 deletions(-) (limited to 'StdLib/LibC/Uefi/Devices/Console/daConsole.c') diff --git a/StdLib/LibC/Uefi/Devices/Console/daConsole.c b/StdLib/LibC/Uefi/Devices/Console/daConsole.c index c579959081..5dfc18acb4 100644 --- a/StdLib/LibC/Uefi/Devices/Console/daConsole.c +++ b/StdLib/LibC/Uefi/Devices/Console/daConsole.c @@ -45,6 +45,12 @@ static const int stdioFlags[NUM_SPECIAL] = { static DeviceNode *ConNode[NUM_SPECIAL]; static ConInstance *ConInstanceList; +static wchar_t *ConReadBuf; + +/* Flags settable by Ioctl */ +static BOOLEAN TtyCooked; +static BOOLEAN TtyEcho; + ssize_t WideTtyCvt( CHAR16 *dest, const char *buf, size_t n) { @@ -127,74 +133,6 @@ da_ConSeek( } } -static -ssize_t -EFIAPI -da_ConRead( - IN OUT struct __filedes *filp, - IN OUT off_t *offset, // Console ignores this - IN size_t BufferSize, - OUT VOID *Buffer -) -{ - EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto; - ConInstance *Stream; - CHAR16 *OutPtr; - EFI_INPUT_KEY Key; - UINTN NumChar; - UINTN Edex; - EFI_STATUS Status = RETURN_SUCCESS; - UINTN i; - - Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction); - // Quick check to see if Stream looks reasonable - if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb' - EFIerrno = RETURN_INVALID_PARAMETER; - return -1; // Looks like a bad This pointer - } - if(Stream->InstanceNum != STDIN_FILENO) { - // Read only valid for stdin - EFIerrno = RETURN_UNSUPPORTED; - return -1; - } - // It looks like things are OK for trying to read - // We will accumulate *BufferSize characters or until we encounter - // an "activation" character. Currently any control character. - Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev; - OutPtr = Buffer; - NumChar = (BufferSize - 1) / sizeof(CHAR16); - i = 0; - do { - if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) { - Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex); - if(Status != RETURN_SUCCESS) { - break; - } - Status = Proto->ReadKeyStroke(Proto, &Key); - if(Status != RETURN_SUCCESS) { - break; - } - } - else { - Key.ScanCode = Stream->UnGetKey.ScanCode; - Key.UnicodeChar = Stream->UnGetKey.UnicodeChar; - Stream->UnGetKey.ScanCode = SCAN_NULL; - Stream->UnGetKey.UnicodeChar = CHAR_NULL; - } - if(Key.ScanCode == SCAN_NULL) { - *OutPtr++ = Key.UnicodeChar; - ++i; - } - if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code - break; - } - } while(i < NumChar); - - *OutPtr = L'\0'; // Terminate the input buffer - EFIerrno = Status; - return (ssize_t)(i * sizeof(CHAR16)); // Will be 0 if we didn't get a key -} - /* Write a NULL terminated WCS to the EFI console. @param[in,out] BufferSize Number of bytes in Buffer. Set to zero if @@ -265,6 +203,109 @@ da_ConWrite( return BufferSize; } +/** Read characters from the console input device. + + @param[in,out] filp Pointer to file descriptor for this file. + @param[in,out] offset Ignored. + @param[in] BufferSize Buffer size, in bytes. + @param[out] Buffer Buffer in which to place the read characters. + + @return Number of bytes actually placed into Buffer. + + @todo Handle encodings other than ASCII-7 and UEFI. +**/ +static +ssize_t +EFIAPI +da_ConRead( + IN OUT struct __filedes *filp, + IN OUT off_t *offset, // Console ignores this + IN size_t BufferSize, + OUT VOID *Buffer +) +{ + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto; + ConInstance *Stream; + wchar_t *OutPtr; + EFI_INPUT_KEY Key; + UINTN NumChar; + UINTN Edex; + EFI_STATUS Status = RETURN_SUCCESS; + UINTN i; + char EchoBuff[MB_CUR_MAX + 1]; + int NumEcho; + + Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction); + // Quick check to see if Stream looks reasonable + if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb' + EFIerrno = RETURN_INVALID_PARAMETER; + return -1; // Looks like a bad This pointer + } + if(Stream->InstanceNum != STDIN_FILENO) { + // Read only valid for stdin + EFIerrno = RETURN_UNSUPPORTED; + return -1; + } + // It looks like things are OK for trying to read + // We will accumulate *BufferSize characters or until we encounter + // an "activation" character. Currently any control character. + Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev; + OutPtr = ConReadBuf; + NumChar = (BufferSize > MAX_INPUT)? MAX_INPUT : BufferSize; + i = 0; + do { + if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) { + Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex); + if(Status != RETURN_SUCCESS) { + break; + } + Status = Proto->ReadKeyStroke(Proto, &Key); + if(Status != RETURN_SUCCESS) { + break; + } + } + else { + Key.ScanCode = Stream->UnGetKey.ScanCode; + Key.UnicodeChar = Stream->UnGetKey.UnicodeChar; + Stream->UnGetKey.ScanCode = SCAN_NULL; + Stream->UnGetKey.UnicodeChar = CHAR_NULL; + } + if(Key.ScanCode == SCAN_NULL) { + NumEcho = 0; + if(TtyCooked && (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) { + *OutPtr++ = CHAR_LINEFEED; + NumEcho = wctomb(EchoBuff, CHAR_LINEFEED); + } + else { + *OutPtr++ = Key.UnicodeChar; + NumEcho = wctomb(EchoBuff, Key.UnicodeChar); + } + ++i; + EchoBuff[NumEcho] = 0; /* Terminate the Echo buffer */ + if(TtyEcho) { + /* Echo the character just input */ + da_ConWrite(&gMD->fdarray[STDOUT_FILENO], NULL, 2, EchoBuff); + } + } + if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code + break; + } + } while(i < NumChar); + + *OutPtr = L'\0'; // Terminate the input buffer + + /* Convert the input buffer and place in Buffer. + If the fully converted input buffer won't fit, write what will and + leave the rest in ConReadBuf with ConReadLeft indicating how many + unconverted characters remain in ConReadBuf. + */ + NumEcho = (int)wcstombs(Buffer, ConReadBuf, BufferSize); /* Re-use NumEcho to hold number of bytes in Buffer */ + /* More work needs to be done before locales other than C can be supported. */ + + EFIerrno = Status; + return (ssize_t)NumEcho; // Will be 0 if we didn't get a key +} + /** Console-specific helper function for the fstat() function. st_size Set to number of characters read for stdin and number written for stdout and stderr. @@ -347,27 +388,28 @@ da_ConIoctl( int EFIAPI da_ConOpen( + DeviceNode *DevNode, struct __filedes *filp, - void *DevInstance, + int DevInstance, // Not used for console devices wchar_t *Path, // Not used for console devices - wchar_t *Flags // Not used for console devices + wchar_t *MPath // Not used for console devices ) { ConInstance *Stream; if((filp == NULL) || - (DevInstance == NULL)) + (DevNode == NULL)) { EFIerrno = RETURN_INVALID_PARAMETER; return -1; } - Stream = (ConInstance *)DevInstance; + Stream = (ConInstance *)DevNode->InstanceList; // Quick check to see if Stream looks reasonable if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb' EFIerrno = RETURN_INVALID_PARAMETER; return -1; // Looks like a bad This pointer } - gMD->StdIo[Stream->InstanceNum] = (ConInstance *)DevInstance; + gMD->StdIo[Stream->InstanceNum] = Stream; filp->f_iflags |= (S_IFREG | _S_IFCHR | _S_ICONSOLE); filp->f_offset = 0; filp->f_ops = &Stream->Abstraction; @@ -448,7 +490,8 @@ __Cons_construct( int i; ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance)); - if(ConInstanceList == NULL) { + ConReadBuf = (wchar_t *)AllocateZeroPool((MAX_INPUT + 1) * sizeof(wchar_t)); + if((ConInstanceList == NULL) || (ConReadBuf == NULL)) { return RETURN_OUT_OF_RESOURCES; } @@ -507,6 +550,10 @@ __Cons_construct( } Stream->Parent = ConNode[i]; } + /* Initialize Ioctl flags until Ioctl is really implemented. */ + TtyCooked = TRUE; + TtyEcho = TRUE; + return Status; } @@ -527,6 +574,9 @@ __Cons_deconstruct( if(ConInstanceList != NULL) { FreePool(ConInstanceList); } + if(ConReadBuf != NULL) { + FreePool(ConReadBuf); + } return RETURN_SUCCESS; } -- cgit v1.2.3