+++ /dev/null
-/** @file\r
- Implementation of the <stdlib.h> functions responsible for communication with\r
- the environment:\r
- - abort(void)\r
- - atexit(void(*handler)(void))\r
- - exit(int status)\r
- - _Exit(int status)\r
-\r
- Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials are licensed and made available under\r
- the terms and conditions of the BSD License that accompanies this distribution.\r
- The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-#include <Uefi.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/ShellLib.h>\r
-\r
-#include <LibConfig.h>\r
-\r
-#include <errno.h>\r
-#include <signal.h>\r
-#include <stdlib.h>\r
-#include <MainData.h>\r
-\r
-/** Internal worker function used by exit().\r
-**/\r
-void exitCleanup(INTN ExitVal);\r
-\r
-/* ################# Public Functions ################################### */\r
-\r
-/** The abort function causes abnormal program termination to occur, unless\r
- the signal SIGABRT is being caught and the signal handler does not return.\r
-\r
- Open streams with unwritten buffered data are not flushed, open\r
- streams are not closed, and temporary files are not removed by abort.\r
-\r
-**/\r
-void\r
-abort(void)\r
-{\r
- if (!gMD->aborting) {\r
- gMD->aborting = TRUE;\r
-\r
- if (gMD->cleanup != NULL) {\r
- gMD->cleanup();\r
- }\r
- }\r
- raise(SIGABRT);\r
- _Exit(EXIT_FAILURE); // In case raise returns.\r
-}\r
-\r
-/** The atexit function registers the function pointed to by func, to be\r
- called without arguments at normal program termination.\r
-\r
- The implementation shall support the registration of\r
- at least 32 functions.\r
-\r
- @return The atexit function returns zero if the registration succeeds,\r
- nonzero if it fails.\r
-**/\r
-int\r
-atexit(void (*handler)(void))\r
-{\r
- int retval = 1;\r
-\r
- if((handler != NULL) && (gMD->num_atexit < ATEXIT_MAX)) {\r
- gMD->atexit_handler[gMD->num_atexit++] = handler;\r
- retval = 0;\r
- }\r
- return retval;\r
-}\r
-\r
-/** The exit function causes normal program termination to occur. If more than\r
- one call to the exit function is executed by a program,\r
- the behavior is undefined.\r
-\r
- First, all functions registered by the atexit function are called, in the\r
- reverse order of their registration. If, during the call to any such function, a\r
- call to the longjmp function is made that would terminate the call to the\r
- registered function, the behavior is undefined.\r
-\r
- Next, all open streams with unwritten buffered data are flushed, all open\r
- streams are closed, and all files created by the tmpfile function\r
- are removed.\r
-\r
- The status returned to the host environment is determined in the same way\r
- as for the _Exit function.\r
-**/\r
-void\r
-exit(int status)\r
-{\r
- exitCleanup((INTN) status);\r
- _Exit(status);\r
-}\r
-\r
-/** The _Exit function causes normal program termination to occur and control\r
- to be returned to the host environment.\r
-\r
- No functions registered by the atexit function or signal handlers\r
- registered by the signal function are called. Open streams with unwritten\r
- buffered data are not flushed, open streams are not closed, and temporary\r
- files are not removed by abort.\r
-\r
- Finally, control is returned to the host environment. If the value of\r
- status is zero, or EXIT_SUCCESS, status is returned unchanged. If the value\r
- of status is EXIT_FAILURE, RETURN_ABORTED is returned.\r
- Otherwise, status is returned unchanged.\r
-**/\r
-void\r
-_Exit(int status)\r
-{\r
- gMD->ExitValue = status; // Save our exit status. Allows a status of 0.\r
- longjmp(gMD->MainExit, 0x55); // Get out of here. longjmp can't return 0. Use 0x55 for a non-zero value.\r
-\r
-#ifdef __GNUC__\r
- __builtin_unreachable (); // Keep GCC happy\r
-#endif\r
-}\r
-\r
-/** If string is a null pointer, the system function determines whether the\r
- host environment has a command processor. If string is not a null pointer,\r
- the system function passes the string pointed to by string to that command\r
- processor to be executed in a manner which the implementation shall\r
- document; this might then cause the program calling system to behave in a\r
- non-conforming manner or to terminate.\r
-\r
- @retval EXIT_FAILURE EFIerrno will contain the EFI status code\r
- indicating the cause of failure.\r
-\r
- @retval EXIT_SUCCESS EFIerrno will contain the EFI status returned\r
- by the executed command string.\r
- @retval 0 If string is NULL, 0 means a command processor\r
- is not available.\r
- @retval 1 If string is NULL, 1 means a command processor\r
- is available.\r
-**/\r
-int\r
-system(const char *string)\r
-{\r
- EFI_STATUS CmdStat;\r
- EFI_STATUS OpStat;\r
- EFI_HANDLE MyHandle = gImageHandle;\r
-\r
- if( string == NULL) {\r
- return 1;\r
- }\r
- (void)AsciiStrToUnicodeStr( string, gMD->UString);\r
- OpStat = ShellExecute( &MyHandle, gMD->UString, FALSE, NULL, &CmdStat);\r
- if(OpStat == RETURN_SUCCESS) {\r
- EFIerrno = CmdStat;\r
- return EXIT_SUCCESS;\r
- }\r
- EFIerrno = OpStat;\r
- return EXIT_FAILURE;\r
-}\r
-\r
-/** The getenv function searches an environment list, provided by the host\r
- environment, for a string that matches the string pointed to by name. The\r
- set of environment names and the method for altering the environment list\r
- are determined by the underlying UEFI Shell implementation.\r
-\r
- @return The getenv function returns a pointer to a string associated with\r
- the matched list member. The string pointed to shall not be\r
- modified by the program, but may be overwritten by a subsequent\r
- call to the getenv function. If the specified name cannot be\r
- found, a null pointer is returned.\r
-**/\r
-char *getenv(const char *name)\r
-{\r
- const CHAR16 *EfiEnv;\r
- char *retval = NULL;\r
-\r
- (void)AsciiStrToUnicodeStr( name, gMD->UString);\r
- EfiEnv = ShellGetEnvironmentVariable(gMD->UString);\r
- if(EfiEnv != NULL) {\r
- retval = UnicodeStrToAsciiStr( EfiEnv, gMD->ASgetenv);\r
- }\r
-\r
- return retval;\r
-}\r
-\r
-\r
-/**\r
- Add or update a variable in the environment list\r
-\r
- @param name Address of a zero terminated name string\r
- @param value Address of a zero terminated value string\r
- @param rewrite TRUE allows overwriting existing values\r
-\r
- @retval Returns 0 upon success\r
- @retval Returns -1 upon failure, sets errno with more information\r
-\r
- Errors\r
-\r
- EINVAL - name is NULL or points to a zero length string\r
- EALREADY - name already set and rewrite set to FALSE\r
- ENODEV - Unable to set non-volatile version of environment variable\r
- ENOMEM - Unable to set volatile version of environment variable\r
- ENOTSUP - Variable storage not supported\r
-\r
-**/\r
-int\r
-setenv (\r
- register const char * name,\r
- register const char * value,\r
- int rewrite\r
- )\r
-{\r
- CONST CHAR16 * HostName;\r
- int retval;\r
- EFI_STATUS Status;\r
- CHAR16 * UName;\r
- CHAR16 * UValue;\r
-\r
- //\r
- // Assume failure\r
- //\r
- retval = -1;\r
-\r
- //\r
- // Validate the inputs\r
- //\r
- errno = EINVAL;\r
- if (( NULL != name ) && ( 0 != *name )) {\r
- //\r
- // Get the storage locations for the unicode strings\r
- //\r
- UName = &gMD->UString[0];\r
- UValue = &gMD->UString2[0];\r
-\r
- //\r
- // Convert the strings\r
- //\r
- AsciiStrToUnicodeStr ( name, UName );\r
- AsciiStrToUnicodeStr ( value, UValue );\r
-\r
- //\r
- // Determine if the string is already present\r
- //\r
- errno = EALREADY;\r
- HostName = ShellGetEnvironmentVariable ( UName );\r
- if ( rewrite || ( NULL == HostName )) {\r
- //\r
- // Support systems that don't have non-volatile memory\r
- //\r
- errno = ENOMEM;\r
- Status = ShellSetEnvironmentVariable ( UName, UValue, TRUE );\r
- if ( EFI_ERROR ( Status )) {\r
- if ( EFI_UNSUPPORTED == Status ) {\r
- errno = ENOTSUP;\r
- }\r
- }\r
- else {\r
- //\r
- // Permanently set the environment variable\r
- //\r
- errno = ENODEV;\r
- Status = ShellSetEnvironmentVariable ( UName, UValue, FALSE );\r
- if ( !EFI_ERROR ( Status )) {\r
- //\r
- // Success\r
- //\r
- errno = 0;\r
- retval = 0;\r
- }\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Return the operation status\r
- //\r
- return retval;\r
-}\r
-\r