mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-29 00:24:07 +02:00
StdLib: Implement da_ConFlush() and flush I/O buffers when closing a console device.
Add header file Efi/SysEfi.h Clean up some indent issues. Implement function da_ConFlush() Modify da_ConClose() to flush its buffers and clean up better upon close. Construct the console instance using the new da_ConFlush() instead of the nullop function. Remove da_ConFlush() from the "Not implemented (yet?)" place holder. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daryl McDaniel <edk2-lists@mc2research.org> Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19587 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
cfb252305a
commit
4e8f2b290e
@ -10,6 +10,7 @@
|
|||||||
The devices status as a wide device is indicatd by _S_IWTTY being set in
|
The devices status as a wide device is indicatd by _S_IWTTY being set in
|
||||||
f_iflags.
|
f_iflags.
|
||||||
|
|
||||||
|
Copyright (c) 2016, Daryl McDaniel. All rights reserved.<BR>
|
||||||
Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
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 terms and conditions of the BSD License that accompanies this distribution.
|
||||||
@ -37,6 +38,7 @@
|
|||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/termios.h>
|
#include <sys/termios.h>
|
||||||
|
#include <Efi/SysEfi.h>
|
||||||
#include <kfile.h>
|
#include <kfile.h>
|
||||||
#include <Device/Device.h>
|
#include <Device/Device.h>
|
||||||
#include <Device/IIO.h>
|
#include <Device/IIO.h>
|
||||||
@ -104,6 +106,65 @@ WideTtyCvt( CHAR16 *dest, const char *buf, ssize_t n, mbstate_t *Cs)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Flush the console's IIO buffers.
|
||||||
|
|
||||||
|
Flush the IIO Input or Output buffers depending upon the mode
|
||||||
|
of the specified file.
|
||||||
|
|
||||||
|
If the console is open for output, write any unwritten data in the output
|
||||||
|
buffer to the console.
|
||||||
|
|
||||||
|
If the console is open for input or output, discard any remaining data
|
||||||
|
in the associated buffers.
|
||||||
|
|
||||||
|
@param[in] filp Pointer to the target file's descriptor structure.
|
||||||
|
|
||||||
|
@retval 0 Always succeeds
|
||||||
|
**/
|
||||||
|
static
|
||||||
|
int
|
||||||
|
EFIAPI
|
||||||
|
da_ConFlush(
|
||||||
|
struct __filedes *filp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cIIO *This;
|
||||||
|
char *MbcsPtr;
|
||||||
|
ssize_t NumProc;
|
||||||
|
void *OutPtr;
|
||||||
|
|
||||||
|
This = filp->devdata;
|
||||||
|
|
||||||
|
if (filp->f_iflags & S_ACC_READ) { // Readable so flush the input buffer
|
||||||
|
This->InBuf->Flush(This->InBuf, UNICODE_STRING_MAX);
|
||||||
|
}
|
||||||
|
if (filp->f_iflags & S_ACC_WRITE) { // Writable so flush the output buffer
|
||||||
|
// At this point, the characters to write are in OutBuf
|
||||||
|
// First, linearize and consume the buffer
|
||||||
|
NumProc = OutBuf->Read(OutBuf, gMD->UString, UNICODE_STRING_MAX-1);
|
||||||
|
if (NumProc > 0) { // Optimization -- Nothing to do if no characters
|
||||||
|
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
|
||||||
|
OutPtr = gMD->UString;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Output device expects narrow characters, convert to MBCS
|
||||||
|
OutPtr = gMD->UString2;
|
||||||
|
// Translate the wide buffer, gMD->UString into MBCS
|
||||||
|
// in the buffer pointed to by OutPtr.
|
||||||
|
// The returned value, NumProc, is the resulting number of bytes.
|
||||||
|
NumProc = wcstombs((char *)OutPtr, (const wchar_t *)gMD->UString, NumProc);
|
||||||
|
((char *)OutPtr)[NumProc] = 0; // Ensure the buffer is terminated
|
||||||
|
}
|
||||||
|
// Do the actual write of the data
|
||||||
|
(void) filp->f_ops->fo_write(filp, NULL, NumProc, OutPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Close an open file.
|
/** Close an open file.
|
||||||
|
|
||||||
@param[in] filp Pointer to the file descriptor structure for this file.
|
@param[in] filp Pointer to the file descriptor structure for this file.
|
||||||
@ -127,6 +188,13 @@ da_ConClose(
|
|||||||
EFIerrno = RETURN_INVALID_PARAMETER;
|
EFIerrno = RETURN_INVALID_PARAMETER;
|
||||||
return -1; // Looks like a bad File Descriptor pointer
|
return -1; // Looks like a bad File Descriptor pointer
|
||||||
}
|
}
|
||||||
|
// Stream and filp look OK, so continue.
|
||||||
|
// Flush the I/O buffers
|
||||||
|
(void) da_ConFlush(filp);
|
||||||
|
|
||||||
|
// Break the connection to IIO
|
||||||
|
filp->devdata = NULL;
|
||||||
|
|
||||||
gMD->StdIo[Stream->InstanceNum] = NULL; // Mark the stream as closed
|
gMD->StdIo[Stream->InstanceNum] = NULL; // Mark the stream as closed
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -188,10 +256,10 @@ da_ConSeek(
|
|||||||
by da_ConWrite are WIDE characters. It is the responsibility of the
|
by da_ConWrite are WIDE characters. It is the responsibility of the
|
||||||
higher-level function(s) to perform any necessary conversions.
|
higher-level function(s) to perform any necessary conversions.
|
||||||
|
|
||||||
@param[in,out] BufferSize Number of characters in Buffer.
|
@param[in,out] BufferSize Number of characters in Buffer.
|
||||||
@param[in] Buffer The WCS string to be displayed
|
@param[in] Buffer The WCS string to be displayed
|
||||||
|
|
||||||
@return The number of Characters written.
|
@return The number of Characters written.
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
ssize_t
|
ssize_t
|
||||||
@ -525,7 +593,7 @@ da_ConOpen(
|
|||||||
wchar_t *MPath // Not used for console devices
|
wchar_t *MPath // Not used for console devices
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ConInstance *Stream;
|
ConInstance *Stream;
|
||||||
UINT32 Instance;
|
UINT32 Instance;
|
||||||
int RetVal = -1;
|
int RetVal = -1;
|
||||||
|
|
||||||
@ -646,68 +714,68 @@ __Cons_construct(
|
|||||||
IIO = New_cIIO();
|
IIO = New_cIIO();
|
||||||
if(IIO == NULL) {
|
if(IIO == NULL) {
|
||||||
FreePool(ConInstanceList);
|
FreePool(ConInstanceList);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Status = RETURN_SUCCESS;
|
Status = RETURN_SUCCESS;
|
||||||
for( i = 0; i < NUM_SPECIAL; ++i) {
|
for( i = 0; i < NUM_SPECIAL; ++i) {
|
||||||
// Get pointer to instance.
|
// Get pointer to instance.
|
||||||
Stream = &ConInstanceList[i];
|
Stream = &ConInstanceList[i];
|
||||||
|
|
||||||
Stream->Cookie = CON_COOKIE;
|
Stream->Cookie = CON_COOKIE;
|
||||||
Stream->InstanceNum = i;
|
Stream->InstanceNum = i;
|
||||||
Stream->CharState.A = 0; // Start in the initial state
|
Stream->CharState.A = 0; // Start in the initial state
|
||||||
|
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case STDIN_FILENO:
|
case STDIN_FILENO:
|
||||||
Stream->Dev = SystemTable->ConIn;
|
Stream->Dev = SystemTable->ConIn;
|
||||||
break;
|
break;
|
||||||
case STDOUT_FILENO:
|
case STDOUT_FILENO:
|
||||||
Stream->Dev = SystemTable->ConOut;
|
Stream->Dev = SystemTable->ConOut;
|
||||||
break;
|
break;
|
||||||
case STDERR_FILENO:
|
case STDERR_FILENO:
|
||||||
if(SystemTable->StdErr == NULL) {
|
if(SystemTable->StdErr == NULL) {
|
||||||
Stream->Dev = SystemTable->ConOut;
|
Stream->Dev = SystemTable->ConOut;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Stream->Dev = SystemTable->StdErr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return RETURN_VOLUME_CORRUPTED; // This is a "should never happen" case.
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Stream->Dev = SystemTable->StdErr;
|
Stream->Abstraction.fo_close = &da_ConClose;
|
||||||
|
Stream->Abstraction.fo_read = &da_ConRead;
|
||||||
|
Stream->Abstraction.fo_write = &da_ConWrite;
|
||||||
|
Stream->Abstraction.fo_stat = &da_ConStat;
|
||||||
|
Stream->Abstraction.fo_lseek = &da_ConSeek;
|
||||||
|
Stream->Abstraction.fo_fcntl = &fnullop_fcntl;
|
||||||
|
Stream->Abstraction.fo_ioctl = &da_ConIoctl;
|
||||||
|
Stream->Abstraction.fo_poll = &da_ConPoll;
|
||||||
|
Stream->Abstraction.fo_flush = &da_ConFlush;
|
||||||
|
Stream->Abstraction.fo_delete = &fbadop_delete;
|
||||||
|
Stream->Abstraction.fo_mkdir = &fbadop_mkdir;
|
||||||
|
Stream->Abstraction.fo_rmdir = &fbadop_rmdir;
|
||||||
|
Stream->Abstraction.fo_rename = &fbadop_rename;
|
||||||
|
|
||||||
|
Stream->NumRead = 0;
|
||||||
|
Stream->NumWritten = 0;
|
||||||
|
Stream->UnGetKey = CHAR_NULL;
|
||||||
|
|
||||||
|
if(Stream->Dev == NULL) {
|
||||||
|
continue; // No device for this stream.
|
||||||
}
|
}
|
||||||
break;
|
ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream,
|
||||||
default:
|
1, sizeof(ConInstance), stdioFlags[i]);
|
||||||
return RETURN_VOLUME_CORRUPTED; // This is a "should never happen" case.
|
if(ConNode[i] == NULL) {
|
||||||
}
|
Status = EFIerrno; // Grab error code that DevRegister produced.
|
||||||
|
break;
|
||||||
Stream->Abstraction.fo_close = &da_ConClose;
|
}
|
||||||
Stream->Abstraction.fo_read = &da_ConRead;
|
Stream->Parent = ConNode[i];
|
||||||
Stream->Abstraction.fo_write = &da_ConWrite;
|
}
|
||||||
Stream->Abstraction.fo_stat = &da_ConStat;
|
/* Initialize Ioctl flags until Ioctl is really implemented. */
|
||||||
Stream->Abstraction.fo_lseek = &da_ConSeek;
|
TtyCooked = TRUE;
|
||||||
Stream->Abstraction.fo_fcntl = &fnullop_fcntl;
|
TtyEcho = TRUE;
|
||||||
Stream->Abstraction.fo_ioctl = &da_ConIoctl;
|
|
||||||
Stream->Abstraction.fo_poll = &da_ConPoll;
|
|
||||||
Stream->Abstraction.fo_flush = &fnullop_flush;
|
|
||||||
Stream->Abstraction.fo_delete = &fbadop_delete;
|
|
||||||
Stream->Abstraction.fo_mkdir = &fbadop_mkdir;
|
|
||||||
Stream->Abstraction.fo_rmdir = &fbadop_rmdir;
|
|
||||||
Stream->Abstraction.fo_rename = &fbadop_rename;
|
|
||||||
|
|
||||||
Stream->NumRead = 0;
|
|
||||||
Stream->NumWritten = 0;
|
|
||||||
Stream->UnGetKey = CHAR_NULL;
|
|
||||||
|
|
||||||
if(Stream->Dev == NULL) {
|
|
||||||
continue; // No device for this stream.
|
|
||||||
}
|
|
||||||
ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream,
|
|
||||||
1, sizeof(ConInstance), stdioFlags[i]);
|
|
||||||
if(ConNode[i] == NULL) {
|
|
||||||
Status = EFIerrno; // Grab error code that DevRegister produced.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Stream->Parent = ConNode[i];
|
|
||||||
}
|
|
||||||
/* Initialize Ioctl flags until Ioctl is really implemented. */
|
|
||||||
TtyCooked = TRUE;
|
|
||||||
TtyEcho = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Status;
|
return Status;
|
||||||
@ -752,14 +820,4 @@ da_ConCntl(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
EFIAPI
|
|
||||||
da_ConFlush(
|
|
||||||
struct __filedes *filp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* Not implemented for Console */
|
#endif /* Not implemented for Console */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user