]>
git.proxmox.com Git - mirror_edk2.git/blob - StdLib/LibC/Main/Main.c
523965fa4368b53d975b3b99027d34593954747b
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 - 2012, 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 Print(L
"ArgvConvert called with %d arguments.\n", Argc
);
85 for(count
= 0; count
< ((Argc
> 5)? 5: Argc
); ++count
) {
86 Print(L
"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 Print(L
"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 Print(L
"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
);
116 string
[AVsz
] = 0; /* NULL terminate the argument */
117 DEBUG((DEBUG_INFO
, "Cvt[%d] %d \"%s\" --> \"%a\"\n", (INT32
)count
, (INT32
)AVsz
, Argv
[count
], nArgv
[count
]));
119 nArgvSize
-= AVsz
+ 1;
121 Print(L
"ABORTING: Internal Argv[%d] conversion error.\n", count
);
136 struct __filedes
*mfd
;
141 ExitVal
= (INTN
)RETURN_SUCCESS
;
142 gMD
= AllocateZeroPool(sizeof(struct __MainData
));
144 ExitVal
= (INTN
)RETURN_OUT_OF_RESOURCES
;
147 /* Initialize data */
148 __sse2_available
= 0;
153 gMD
->ClocksPerSecond
= 1;
154 gMD
->AppStartTime
= (clock_t)((UINT32
)time(NULL
));
156 // Initialize file descriptors
158 for(i
= 0; i
< (FOPEN_MAX
); ++i
) {
159 mfd
[i
].MyFD
= (UINT16
)i
;
162 i
= open("stdin:", O_RDONLY
, 0444);
164 i
= open("stdout:", O_WRONLY
, 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 ExitVal
= (INTN
)main( (int)Argc
, gMD
->NArgV
);
182 exitCleanup(ExitVal
);
184 /* You reach here if:
185 * normal return from main()
186 * call to _Exit(), either directly or through exit().
188 ExitVal
= (INTN
)gMD
->ExitValue
;
191 if( ExitVal
== EXIT_FAILURE
) {
192 ExitVal
= RETURN_ABORTED
;
195 /* Close any open files */
196 for(i
= OPEN_MAX
- 1; i
>= 0; --i
) {
197 (void)close(i
); // Close properly handles closing a closed file.
200 /* Free the global MainData structure */
202 if(gMD
->NCmdLine
!= NULL
) {
203 FreePool( gMD
->NCmdLine
);