]>
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 - 2011, 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>
31 #include <sys/EfiSysCall.h>
33 extern int main( int, char**);
34 extern int __sse2_available
;
36 struct __MainData
*gMD
;
38 /* Worker function to keep GCC happy. */
44 /** Clean up data as required by the exit() function.
48 exitCleanup(INTN ExitVal
)
50 void (*CleanUp
)(void); // Pointer to Cleanup Function
54 gMD
->ExitValue
= (int)ExitVal
;
55 CleanUp
= gMD
->cleanup
; // Preserve the pointer to the Cleanup Function
57 // Call all registered atexit functions in reverse order
61 (gMD
->atexit_handler
[--i
])();
65 if (CleanUp
!= NULL
) {
71 /* Create mbcs versions of the Argv strings. */
74 ArgvConvert(UINTN Argc
, CHAR16
**Argv
)
76 size_t AVsz
; /* Size of a single nArgv string */
80 INTN nArgvSize
; /* Cumulative size of narrow Argv[i] */
83 Print(L
"ArgvConvert called with %d arguments.\n", Argc
);
84 for(count
= 0; count
< ((Argc
> 5)? 5: Argc
); ++count
) {
85 Print(L
"Argument[%d] = \"%s\".\n", count
, Argv
[count
]);
90 /* Determine space needed for narrow Argv strings. */
91 for(count
= 0; count
< Argc
; ++count
) {
92 AVsz
= wcstombs(NULL
, Argv
[count
], ARG_MAX
);
94 Print(L
"ABORTING: Argv[%d] contains an unconvertable character.\n", count
);
101 /* Reserve space for the converted strings. */
102 gMD
->NCmdLine
= (char *)AllocateZeroPool(nArgvSize
+1);
103 if(gMD
->NCmdLine
== NULL
) {
104 Print(L
"ABORTING: Insufficient memory.\n");
109 /* Convert Argument Strings. */
111 string
= gMD
->NCmdLine
;
112 for(count
= 0; count
< Argc
; ++count
) {
113 nArgv
[count
] = string
;
114 AVsz
= wcstombs(string
, Argv
[count
], nArgvSize
);
115 string
[AVsz
] = 0; /* NULL terminate the argument */
116 DEBUG((DEBUG_INFO
, "Cvt[%d] %d \"%s\" --> \"%a\"\n", (INT32
)count
, (INT32
)AVsz
, Argv
[count
], nArgv
[count
]));
118 nArgvSize
-= AVsz
+ 1;
120 Print(L
"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;
153 gMD
->ClocksPerSecond
= 1; // For NT32 only
154 gMD
->AppStartTime
= 1; // For NT32 only
156 gMD
->ClocksPerSecond
= (clock_t)GetPerformanceCounterProperties( NULL
, NULL
);
157 gMD
->AppStartTime
= (clock_t)GetPerformanceCounter();
158 #endif /* NT32 dvm */
160 // Initialize file descriptors
162 for(i
= 0; i
< (FOPEN_MAX
); ++i
) {
163 mfd
[i
].MyFD
= (UINT16
)i
;
166 i
= open("stdin:", O_RDONLY
, 0444);
168 i
= open("stdout:", O_WRONLY
, 0222);
170 i
= open("stderr:", O_WRONLY
, 0222);
174 Print(L
"ERROR Initializing Standard IO: %a.\n %r\n",
175 strerror(errno
), EFIerrno
);
178 /* Create mbcs versions of the Argv strings. */
179 nArgv
= ArgvConvert(Argc
, Argv
);
181 ExitVal
= (INTN
)RETURN_INVALID_PARAMETER
;
184 if( setjmp(gMD
->MainExit
) == 0) {
185 ExitVal
= (INTN
)main( (int)Argc
, gMD
->NArgV
);
186 exitCleanup(ExitVal
);
188 /* You reach here if:
189 * normal return from main()
190 * call to _Exit(), either directly or through exit().
192 ExitVal
= (INTN
)gMD
->ExitValue
;
195 if( ExitVal
== EXIT_FAILURE
) {
196 ExitVal
= RETURN_ABORTED
;
199 /* Close any open files */
200 for(i
= OPEN_MAX
- 1; i
>= 0; --i
) {
201 (void)close(i
); // Close properly handles closing a closed file.
204 /* Free the global MainData structure */
206 if(gMD
->NCmdLine
!= NULL
) {
207 FreePool( gMD
->NCmdLine
);