]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/LibC/Main/Main.c
2 Establish the program environment and the "main" entry point.
4 All of the global data in the gMD structure is initialized to 0, NULL, or
5 SIG_DFL; as appropriate.
7 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials are licensed and made available under
9 the terms and conditions of the BSD License that accompanies this distribution.
10 The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/UefiLib.h>
18 #include <Library/DebugLib.h>
20 #include <Library/ShellCEntryLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/TimerLib.h>
24 #include <LibConfig.h>
34 extern int main( int, char**);
35 extern int __sse2_available
;
37 struct __MainData
*gMD
;
39 /* Worker function to keep GCC happy. */
45 /** Clean up data as required by the exit() function.
49 exitCleanup(INTN ExitVal
)
51 void (*CleanUp
)(void); // Pointer to Cleanup Function
55 gMD
->ExitValue
= (int)ExitVal
;
56 CleanUp
= gMD
->cleanup
; // Preserve the pointer to the Cleanup Function
58 // Call all registered atexit functions in reverse order
62 (gMD
->atexit_handler
[--i
])();
66 if (CleanUp
!= NULL
) {
72 /* Create mbcs versions of the Argv strings. */
75 ArgvConvert(UINTN Argc
, CHAR16
**Argv
)
77 ssize_t AVsz
; /* Size of a single nArgv string, or -1 */
81 INTN nArgvSize
; /* Cumulative size of narrow Argv[i] */
84 DEBUG((DEBUG_INIT
, "ArgvConvert called with %d arguments.\n", Argc
));
85 for(count
= 0; count
< ((Argc
> 5)? 5: Argc
); ++count
) {
86 DEBUG((DEBUG_INIT
, "Argument[%d] = \"%s\".\n", count
, Argv
[count
]));
91 /* Determine space needed for narrow Argv strings. */
92 for(count
= 0; count
< Argc
; ++count
) {
93 AVsz
= (ssize_t
)wcstombs(NULL
, Argv
[count
], ARG_MAX
);
95 DEBUG((DEBUG_ERROR
, "ABORTING: Argv[%d] contains an unconvertable character.\n", count
));
102 /* Reserve space for the converted strings. */
103 gMD
->NCmdLine
= (char *)AllocateZeroPool(nArgvSize
+1);
104 if(gMD
->NCmdLine
== NULL
) {
105 DEBUG((DEBUG_ERROR
, "ABORTING: Insufficient memory.\n"));
110 /* Convert Argument Strings. */
112 string
= gMD
->NCmdLine
;
113 for(count
= 0; count
< Argc
; ++count
) {
114 nArgv
[count
] = string
;
115 AVsz
= wcstombs(string
, Argv
[count
], nArgvSize
) + 1;
116 DEBUG((DEBUG_INFO
, "Cvt[%d] %d \"%s\" --> \"%a\"\n", (INT32
)count
, (INT32
)AVsz
, Argv
[count
], nArgv
[count
]));
120 DEBUG((DEBUG_ERROR
, "ABORTING: Internal Argv[%d] conversion error.\n", count
));
135 struct __filedes
*mfd
;
140 ExitVal
= (INTN
)RETURN_SUCCESS
;
141 gMD
= AllocateZeroPool(sizeof(struct __MainData
));
143 ExitVal
= (INTN
)RETURN_OUT_OF_RESOURCES
;
146 /* Initialize data */
147 __sse2_available
= 0;
152 gMD
->ClocksPerSecond
= 1;
153 gMD
->AppStartTime
= (clock_t)((UINT32
)time(NULL
));
155 // Initialize file descriptors
157 for(i
= 0; i
< (FOPEN_MAX
); ++i
) {
158 mfd
[i
].MyFD
= (UINT16
)i
;
161 DEBUG((DEBUG_INIT
, "StdLib: Open Standard IO.\n"));
162 i
= open("stdin:", (O_RDONLY
| O_TTY_INIT
), 0444);
164 i
= open("stdout:", (O_WRONLY
| O_TTY_INIT
), 0222);
166 i
= open("stderr:", O_WRONLY
, 0222);
170 Print(L
"ERROR Initializing Standard IO: %a.\n %r\n",
171 strerror(errno
), EFIerrno
);
174 /* Create mbcs versions of the Argv strings. */
175 nArgv
= ArgvConvert(Argc
, Argv
);
177 ExitVal
= (INTN
)RETURN_INVALID_PARAMETER
;
180 if( setjmp(gMD
->MainExit
) == 0) {
181 errno
= 0; // Clean up any "scratch" values from startup.
182 ExitVal
= (INTN
)main( (int)Argc
, gMD
->NArgV
);
183 exitCleanup(ExitVal
);
185 /* You reach here if:
186 * normal return from main()
187 * call to _Exit(), either directly or through exit().
189 ExitVal
= (INTN
)gMD
->ExitValue
;
192 if( ExitVal
== EXIT_FAILURE
) {
193 ExitVal
= RETURN_ABORTED
;
196 /* Close any open files */
197 for(i
= OPEN_MAX
- 1; i
>= 0; --i
) {
198 (void)close(i
); // Close properly handles closing a closed file.
201 /* Free the global MainData structure */
203 if(gMD
->NCmdLine
!= NULL
) {
204 FreePool( gMD
->NCmdLine
);