Files
system76-edk2/StdLib/LibC/StdLib/Environs.c
darylm503 2aa62f2bc9 Standard Libraries for EDK II.
This set of three packages: AppPkg, StdLib, StdLibPrivateInternalFiles; contains the implementation of libraries based upon non-UEFI standards such as ISO/IEC-9899, the library portion of the C Language Standard, POSIX, etc.

AppPkg contains applications that make use of the standard libraries defined in the StdLib Package.

StdLib contains header (include) files and the implementations of the standard libraries.

StdLibPrivateInternalFiles contains files for the exclusive use of the library implementations in StdLib.  These files should never be directly referenced from applications or other code.


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11600 6f19259b-4bc3-4df7-8a09-765794883524
2011-04-27 21:42:16 +00:00

209 lines
6.7 KiB
C

/** @file
Implementation of the <stdlib.h> functions responsible for communication with
the environment:
- abort(void)
- atexit(void(*handler)(void))
- exit(int status)
- _Exit(int status)
Copyright (c) 2010, 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 that 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 <Library/UefiBootServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/ShellLib.h>
#include <LibConfig.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <MainData.h>
/* ################# Public Functions ################################### */
/** The abort function causes abnormal program termination to occur, unless
the signal SIGABRT is being caught and the signal handler does not return.
Open streams with unwritten buffered data are not flushed, open
streams are not closed, and temporary files are not removed by abort.
**/
void
abort(void)
{
if (!gMD->aborting) {
gMD->aborting = TRUE;
if (gMD->cleanup != NULL) {
gMD->cleanup();
}
}
raise(SIGABRT);
_Exit(EXIT_FAILURE); // In case raise returns.
}
/** The atexit function registers the function pointed to by func, to be
called without arguments at normal program termination.
The implementation shall support the registration of
at least 32 functions.
@return The atexit function returns zero if the registration succeeds,
nonzero if it fails.
**/
int
atexit(void (*handler)(void))
{
int retval = 1;
if((handler != NULL) && (gMD->num_atexit < ATEXIT_MAX)) {
gMD->atexit_handler[gMD->num_atexit++] = handler;
retval = 0;
}
return retval;
}
/** The exit function causes normal program termination to occur. If more than
one call to the exit function is executed by a program,
the behavior is undefined.
First, all functions registered by the atexit function are called, in the
reverse order of their registration. If, during the call to any such function, a
call to the longjmp function is made that would terminate the call to the
registered function, the behavior is undefined.
Next, all open streams with unwritten buffered data are flushed, all open
streams are closed, and all files created by the tmpfile function
are removed.
The status returned to the host environment is determined in the same way
as for the _Exit function.
**/
void
exit(int status)
{
int i = gMD->num_atexit;
// Call all registered atexit functions in reverse order
if( i > 0) {
do {
(gMD->atexit_handler[--i])();
} while( i > 0);
}
if (gMD->cleanup != NULL) {
gMD->cleanup();
}
_Exit(status);
}
typedef
EFI_STATUS
(EFIAPI *ExitFuncPtr)(
IN EFI_HANDLE ImageHandle,
IN EFI_STATUS ExitStatus,
IN UINTN ExitDataSize,
IN CHAR16 *ExitData OPTIONAL
) __noreturn;
/** The _Exit function causes normal program termination to occur and control
to be returned to the host environment.
No functions registered by the atexit function or signal handlers
registered by the signal function are called. Open streams with unwritten
buffered data are not flushed, open streams are not closed, and temporary
files are not removed by abort.
Finally, control is returned to the host environment. If the value of
status is zero, or EXIT_SUCCESS, status is returned unchanged. If the value
of status is EXIT_FAILURE, RETURN_ABORTED is returned.
Otherwise, status is returned unchanged.
**/
void
_Exit(int status)
{
RETURN_STATUS ExitVal = (RETURN_STATUS)status;
ExitFuncPtr ExitFunc;
if( ExitVal == EXIT_FAILURE) {
ExitVal = RETURN_ABORTED;
}
ExitFunc = (ExitFuncPtr)gBS->Exit;
//gBS->Exit(gImageHandle, ExitVal, 0, NULL); /* abort() */
ExitFunc(gImageHandle, ExitVal, 0, NULL); /* abort() */
}
/** If string is a null pointer, the system function determines whether the
host environment has a command processor. If string is not a null pointer,
the system function passes the string pointed to by string to that command
processor to be executed in a manner which the implementation shall
document; this might then cause the program calling system to behave in a
non-conforming manner or to terminate.
@retval EXIT_FAILURE EFIerrno will contain the EFI status code
indicating the cause of failure.
@retval EXIT_SUCCESS EFIerrno will contain the EFI status returned
by the executed command string.
@retval 0 If string is NULL, 0 means a command processor
is not available.
@retval 1 If string is NULL, 1 means a command processor
is available.
**/
int
system(const char *string)
{
EFI_STATUS CmdStat;
EFI_STATUS OpStat;
EFI_HANDLE MyHandle = gImageHandle;
if( string == NULL) {
return 1;
}
(void)AsciiStrToUnicodeStr( string, gMD->UString);
OpStat = ShellExecute( &MyHandle, gMD->UString, FALSE, NULL, &CmdStat);
if(OpStat == RETURN_SUCCESS) {
EFIerrno = CmdStat;
return EXIT_SUCCESS;
}
EFIerrno = OpStat;
return EXIT_FAILURE;
}
/** The getenv function searches an environment list, provided by the host
environment, for a string that matches the string pointed to by name. The
set of environment names and the method for altering the environment list
are determined by the underlying UEFI Shell implementation.
@return The getenv function returns a pointer to a string associated with
the matched list member. The string pointed to shall not be
modified by the program, but may be overwritten by a subsequent
call to the getenv function. If the specified name cannot be
found, a null pointer is returned.
**/
char *getenv(const char *name)
{
const CHAR16 *EfiEnv;
char *retval = NULL;
(void)AsciiStrToUnicodeStr( name, gMD->UString);
EfiEnv = ShellGetEnvironmentVariable(gMD->UString);
if(EfiEnv != NULL) {
retval = UnicodeStrToAsciiStr( EfiEnv, gMD->ASgetenv);
}
return retval;
}