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:
Daryl McDaniel 2016-01-06 00:05:02 +00:00 committed by darylm503
parent cfb252305a
commit 4e8f2b290e
1 changed files with 127 additions and 69 deletions

View File

@ -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;
} }
@ -684,7 +752,7 @@ __Cons_construct(
Stream->Abstraction.fo_fcntl = &fnullop_fcntl; Stream->Abstraction.fo_fcntl = &fnullop_fcntl;
Stream->Abstraction.fo_ioctl = &da_ConIoctl; Stream->Abstraction.fo_ioctl = &da_ConIoctl;
Stream->Abstraction.fo_poll = &da_ConPoll; Stream->Abstraction.fo_poll = &da_ConPoll;
Stream->Abstraction.fo_flush = &fnullop_flush; Stream->Abstraction.fo_flush = &da_ConFlush;
Stream->Abstraction.fo_delete = &fbadop_delete; Stream->Abstraction.fo_delete = &fbadop_delete;
Stream->Abstraction.fo_mkdir = &fbadop_mkdir; Stream->Abstraction.fo_mkdir = &fbadop_mkdir;
Stream->Abstraction.fo_rmdir = &fbadop_rmdir; Stream->Abstraction.fo_rmdir = &fbadop_rmdir;
@ -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 */