]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/StdLib/Environs.c
Standard Libraries for EDK II.
[mirror_edk2.git] / StdLib / LibC / StdLib / Environs.c
CommitLineData
2aa62f2b 1/** @file\r
2 Implementation of the <stdlib.h> functions responsible for communication with\r
3 the environment:\r
4 - abort(void)\r
5 - atexit(void(*handler)(void))\r
6 - exit(int status)\r
7 - _Exit(int status)\r
8\r
9 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
10 This program and the accompanying materials are licensed and made available under\r
11 the terms and conditions of the BSD License that accompanies this distribution.\r
12 The full text of the license may be found at\r
13 http://opensource.org/licenses/bsd-license.php.\r
14\r
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
17\r
18**/\r
19#include <Uefi.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Library/BaseLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/ShellLib.h>\r
24\r
25#include <LibConfig.h>\r
26\r
27#include <errno.h>\r
28#include <signal.h>\r
29#include <stdlib.h>\r
30#include <MainData.h>\r
31\r
32/* ################# Public Functions ################################### */\r
33\r
34/** The abort function causes abnormal program termination to occur, unless\r
35 the signal SIGABRT is being caught and the signal handler does not return.\r
36\r
37 Open streams with unwritten buffered data are not flushed, open\r
38 streams are not closed, and temporary files are not removed by abort.\r
39\r
40**/\r
41void\r
42abort(void)\r
43{\r
44 if (!gMD->aborting) {\r
45 gMD->aborting = TRUE;\r
46\r
47 if (gMD->cleanup != NULL) {\r
48 gMD->cleanup();\r
49 }\r
50 }\r
51 raise(SIGABRT);\r
52 _Exit(EXIT_FAILURE); // In case raise returns.\r
53}\r
54\r
55/** The atexit function registers the function pointed to by func, to be\r
56 called without arguments at normal program termination.\r
57\r
58 The implementation shall support the registration of\r
59 at least 32 functions.\r
60\r
61 @return The atexit function returns zero if the registration succeeds,\r
62 nonzero if it fails.\r
63**/\r
64int\r
65atexit(void (*handler)(void))\r
66{\r
67 int retval = 1;\r
68\r
69 if((handler != NULL) && (gMD->num_atexit < ATEXIT_MAX)) {\r
70 gMD->atexit_handler[gMD->num_atexit++] = handler;\r
71 retval = 0;\r
72 }\r
73 return retval;\r
74}\r
75\r
76/** The exit function causes normal program termination to occur. If more than\r
77 one call to the exit function is executed by a program,\r
78 the behavior is undefined.\r
79\r
80 First, all functions registered by the atexit function are called, in the\r
81 reverse order of their registration. If, during the call to any such function, a\r
82 call to the longjmp function is made that would terminate the call to the\r
83 registered function, the behavior is undefined.\r
84\r
85 Next, all open streams with unwritten buffered data are flushed, all open\r
86 streams are closed, and all files created by the tmpfile function\r
87 are removed.\r
88\r
89 The status returned to the host environment is determined in the same way\r
90 as for the _Exit function.\r
91**/\r
92void\r
93exit(int status)\r
94{\r
95 int i = gMD->num_atexit;\r
96\r
97 // Call all registered atexit functions in reverse order\r
98 if( i > 0) {\r
99 do {\r
100 (gMD->atexit_handler[--i])();\r
101 } while( i > 0);\r
102 }\r
103\r
104 if (gMD->cleanup != NULL) {\r
105 gMD->cleanup();\r
106 }\r
107 _Exit(status);\r
108}\r
109\r
110typedef\r
111EFI_STATUS\r
112(EFIAPI *ExitFuncPtr)(\r
113 IN EFI_HANDLE ImageHandle,\r
114 IN EFI_STATUS ExitStatus,\r
115 IN UINTN ExitDataSize,\r
116 IN CHAR16 *ExitData OPTIONAL\r
117) __noreturn;\r
118\r
119/** The _Exit function causes normal program termination to occur and control\r
120 to be returned to the host environment.\r
121\r
122 No functions registered by the atexit function or signal handlers\r
123 registered by the signal function are called. Open streams with unwritten\r
124 buffered data are not flushed, open streams are not closed, and temporary\r
125 files are not removed by abort.\r
126\r
127 Finally, control is returned to the host environment. If the value of\r
128 status is zero, or EXIT_SUCCESS, status is returned unchanged. If the value\r
129 of status is EXIT_FAILURE, RETURN_ABORTED is returned.\r
130 Otherwise, status is returned unchanged.\r
131**/\r
132void\r
133_Exit(int status)\r
134{\r
135 RETURN_STATUS ExitVal = (RETURN_STATUS)status;\r
136 ExitFuncPtr ExitFunc;\r
137\r
138 if( ExitVal == EXIT_FAILURE) {\r
139 ExitVal = RETURN_ABORTED;\r
140 }\r
141\r
142 ExitFunc = (ExitFuncPtr)gBS->Exit;\r
143\r
144 //gBS->Exit(gImageHandle, ExitVal, 0, NULL); /* abort() */\r
145 ExitFunc(gImageHandle, ExitVal, 0, NULL); /* abort() */\r
146}\r
147\r
148/** If string is a null pointer, the system function determines whether the\r
149 host environment has a command processor. If string is not a null pointer,\r
150 the system function passes the string pointed to by string to that command\r
151 processor to be executed in a manner which the implementation shall\r
152 document; this might then cause the program calling system to behave in a\r
153 non-conforming manner or to terminate.\r
154\r
155 @retval EXIT_FAILURE EFIerrno will contain the EFI status code\r
156 indicating the cause of failure.\r
157\r
158 @retval EXIT_SUCCESS EFIerrno will contain the EFI status returned\r
159 by the executed command string.\r
160 @retval 0 If string is NULL, 0 means a command processor\r
161 is not available.\r
162 @retval 1 If string is NULL, 1 means a command processor\r
163 is available.\r
164**/\r
165int\r
166system(const char *string)\r
167{\r
168 EFI_STATUS CmdStat;\r
169 EFI_STATUS OpStat;\r
170 EFI_HANDLE MyHandle = gImageHandle;\r
171\r
172 if( string == NULL) {\r
173 return 1;\r
174 }\r
175 (void)AsciiStrToUnicodeStr( string, gMD->UString);\r
176 OpStat = ShellExecute( &MyHandle, gMD->UString, FALSE, NULL, &CmdStat);\r
177 if(OpStat == RETURN_SUCCESS) {\r
178 EFIerrno = CmdStat;\r
179 return EXIT_SUCCESS;\r
180 }\r
181 EFIerrno = OpStat;\r
182 return EXIT_FAILURE;\r
183}\r
184\r
185/** The getenv function searches an environment list, provided by the host\r
186 environment, for a string that matches the string pointed to by name. The\r
187 set of environment names and the method for altering the environment list\r
188 are determined by the underlying UEFI Shell implementation.\r
189\r
190 @return The getenv function returns a pointer to a string associated with\r
191 the matched list member. The string pointed to shall not be\r
192 modified by the program, but may be overwritten by a subsequent\r
193 call to the getenv function. If the specified name cannot be\r
194 found, a null pointer is returned.\r
195**/\r
196char *getenv(const char *name)\r
197{\r
198 const CHAR16 *EfiEnv;\r
199 char *retval = NULL;\r
200\r
201 (void)AsciiStrToUnicodeStr( name, gMD->UString);\r
202 EfiEnv = ShellGetEnvironmentVariable(gMD->UString);\r
203 if(EfiEnv != NULL) {\r
204 retval = UnicodeStrToAsciiStr( EfiEnv, gMD->ASgetenv);\r
205 }\r
206\r
207 return retval;\r
208}\r