]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/StdLib/Environs.c
Add Socket Libraries.
[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
53e1e5c6 9 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
2aa62f2b 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
53e1e5c6 13 http://opensource.org/licenses/bsd-license.\r
2aa62f2b 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
d7ce7006 32/** Internal worker function used by exit().\r
33**/\r
34void exitCleanup(INTN ExitVal);\r
35\r
2aa62f2b 36/* ################# Public Functions ################################### */\r
37\r
38/** The abort function causes abnormal program termination to occur, unless\r
39 the signal SIGABRT is being caught and the signal handler does not return.\r
40\r
41 Open streams with unwritten buffered data are not flushed, open\r
42 streams are not closed, and temporary files are not removed by abort.\r
43\r
44**/\r
45void\r
46abort(void)\r
47{\r
48 if (!gMD->aborting) {\r
49 gMD->aborting = TRUE;\r
50\r
51 if (gMD->cleanup != NULL) {\r
52 gMD->cleanup();\r
53 }\r
54 }\r
55 raise(SIGABRT);\r
56 _Exit(EXIT_FAILURE); // In case raise returns.\r
57}\r
58\r
59/** The atexit function registers the function pointed to by func, to be\r
60 called without arguments at normal program termination.\r
61\r
62 The implementation shall support the registration of\r
63 at least 32 functions.\r
64\r
65 @return The atexit function returns zero if the registration succeeds,\r
66 nonzero if it fails.\r
67**/\r
68int\r
69atexit(void (*handler)(void))\r
70{\r
71 int retval = 1;\r
72\r
73 if((handler != NULL) && (gMD->num_atexit < ATEXIT_MAX)) {\r
74 gMD->atexit_handler[gMD->num_atexit++] = handler;\r
75 retval = 0;\r
76 }\r
77 return retval;\r
78}\r
79\r
80/** The exit function causes normal program termination to occur. If more than\r
81 one call to the exit function is executed by a program,\r
82 the behavior is undefined.\r
83\r
84 First, all functions registered by the atexit function are called, in the\r
85 reverse order of their registration. If, during the call to any such function, a\r
86 call to the longjmp function is made that would terminate the call to the\r
87 registered function, the behavior is undefined.\r
88\r
89 Next, all open streams with unwritten buffered data are flushed, all open\r
90 streams are closed, and all files created by the tmpfile function\r
91 are removed.\r
92\r
93 The status returned to the host environment is determined in the same way\r
94 as for the _Exit function.\r
95**/\r
96void\r
97exit(int status)\r
98{\r
d7ce7006 99 exitCleanup((INTN) status);\r
2aa62f2b 100 _Exit(status);\r
101}\r
102\r
2aa62f2b 103/** The _Exit function causes normal program termination to occur and control\r
104 to be returned to the host environment.\r
105\r
106 No functions registered by the atexit function or signal handlers\r
107 registered by the signal function are called. Open streams with unwritten\r
108 buffered data are not flushed, open streams are not closed, and temporary\r
109 files are not removed by abort.\r
110\r
111 Finally, control is returned to the host environment. If the value of\r
112 status is zero, or EXIT_SUCCESS, status is returned unchanged. If the value\r
113 of status is EXIT_FAILURE, RETURN_ABORTED is returned.\r
114 Otherwise, status is returned unchanged.\r
115**/\r
116void\r
117_Exit(int status)\r
118{\r
d7ce7006 119 gMD->ExitValue = status; // Save our exit status. Allows a status of 0.\r
120 longjmp(gMD->MainExit, 0x55); // Get out of here. longjmp can't return 0. Use 0x55 for a non-zero value.\r
2aa62f2b 121\r
d7ce7006 122#ifdef __GNUC__\r
123 __builtin__Exit(status); /* Keep GCC happy - never reached */\r
124#endif\r
2aa62f2b 125}\r
126\r
127/** If string is a null pointer, the system function determines whether the\r
128 host environment has a command processor. If string is not a null pointer,\r
129 the system function passes the string pointed to by string to that command\r
130 processor to be executed in a manner which the implementation shall\r
131 document; this might then cause the program calling system to behave in a\r
132 non-conforming manner or to terminate.\r
133\r
134 @retval EXIT_FAILURE EFIerrno will contain the EFI status code\r
135 indicating the cause of failure.\r
136\r
137 @retval EXIT_SUCCESS EFIerrno will contain the EFI status returned\r
138 by the executed command string.\r
139 @retval 0 If string is NULL, 0 means a command processor\r
140 is not available.\r
141 @retval 1 If string is NULL, 1 means a command processor\r
142 is available.\r
143**/\r
144int\r
145system(const char *string)\r
146{\r
147 EFI_STATUS CmdStat;\r
148 EFI_STATUS OpStat;\r
149 EFI_HANDLE MyHandle = gImageHandle;\r
150\r
151 if( string == NULL) {\r
152 return 1;\r
153 }\r
154 (void)AsciiStrToUnicodeStr( string, gMD->UString);\r
155 OpStat = ShellExecute( &MyHandle, gMD->UString, FALSE, NULL, &CmdStat);\r
156 if(OpStat == RETURN_SUCCESS) {\r
157 EFIerrno = CmdStat;\r
158 return EXIT_SUCCESS;\r
159 }\r
160 EFIerrno = OpStat;\r
161 return EXIT_FAILURE;\r
162}\r
163\r
164/** The getenv function searches an environment list, provided by the host\r
165 environment, for a string that matches the string pointed to by name. The\r
166 set of environment names and the method for altering the environment list\r
167 are determined by the underlying UEFI Shell implementation.\r
168\r
169 @return The getenv function returns a pointer to a string associated with\r
170 the matched list member. The string pointed to shall not be\r
171 modified by the program, but may be overwritten by a subsequent\r
172 call to the getenv function. If the specified name cannot be\r
173 found, a null pointer is returned.\r
174**/\r
175char *getenv(const char *name)\r
176{\r
177 const CHAR16 *EfiEnv;\r
178 char *retval = NULL;\r
179\r
180 (void)AsciiStrToUnicodeStr( name, gMD->UString);\r
181 EfiEnv = ShellGetEnvironmentVariable(gMD->UString);\r
182 if(EfiEnv != NULL) {\r
183 retval = UnicodeStrToAsciiStr( EfiEnv, gMD->ASgetenv);\r
184 }\r
185\r
186 return retval;\r
187}\r
53e1e5c6 188\r
189\r
190/**\r
191 Add or update a variable in the environment list\r
192\r
193 @param name Address of a zero terminated name string\r
194 @param value Address of a zero terminated value string\r
195 @param rewrite TRUE allows overwriting existing values\r
196\r
197 @retval Returns 0 upon success\r
198 @retval Returns -1 upon failure, sets errno with more information\r
199\r
200 Errors\r
201\r
202 EINVAL - name is NULL or points to a zero length string\r
203 EALREADY - name already set and rewrite set to FALSE\r
204 ENODEV - Unable to set non-volatile version of environment variable\r
205 ENOMEM - Unable to set volatile version of environment variable\r
206 ENOTSUP - Variable storage not supported\r
207\r
208**/\r
209int\r
210setenv (\r
211 register const char * name,\r
212 register const char * value,\r
213 int rewrite\r
214 )\r
215{\r
216 CONST CHAR16 * HostName;\r
217 int retval;\r
218 EFI_STATUS Status;\r
219 CHAR16 * UName;\r
220 CHAR16 * UValue;\r
221\r
222 //\r
223 // Assume failure\r
224 //\r
225 retval = -1;\r
226\r
227 //\r
228 // Validate the inputs\r
229 //\r
230 errno = EINVAL;\r
231 if (( NULL != name ) && ( 0 != *name )) {\r
232 //\r
233 // Get the storage locations for the unicode strings\r
234 //\r
235 UName = &gMD->UString[0];\r
236 UValue = &gMD->UString2[0];\r
237\r
238 //\r
239 // Convert the strings\r
240 //\r
241 AsciiStrToUnicodeStr ( name, UName );\r
242 AsciiStrToUnicodeStr ( value, UValue );\r
243\r
244 //\r
245 // Determine if the string is already present\r
246 //\r
247 errno = EALREADY;\r
248 HostName = ShellGetEnvironmentVariable ( UName );\r
249 if ( rewrite || ( NULL == HostName )) {\r
250 //\r
251 // Support systems that don't have non-volatile memory\r
252 //\r
253 errno = ENOMEM;\r
254 Status = ShellSetEnvironmentVariable ( UName, UValue, TRUE );\r
255 if ( EFI_ERROR ( Status )) {\r
256 if ( EFI_UNSUPPORTED == Status ) {\r
257 errno = ENOTSUP;\r
258 }\r
259 }\r
260 else {\r
261 //\r
262 // Permanently set the environment variable\r
263 //\r
264 errno = ENODEV;\r
265 Status = ShellSetEnvironmentVariable ( UName, UValue, FALSE );\r
266 if ( !EFI_ERROR ( Status )) {\r
267 //\r
268 // Success\r
269 //\r
270 errno = 0;\r
271 retval = 0;\r
272 }\r
273 }\r
274 }\r
275 }\r
276\r
277 //\r
278 // Return the operation status\r
279 //\r
280 return retval;\r
281}\r
282\r