mirror of https://github.com/acidanthera/audk.git
ShellPkg/Shell: Fix reporting of exit status in ShellProtocol.Execute
When the exit status of the command run by the shell is other than SHELL_SUCCESS, the shell image will now exit with EFI_ABORTED, placing the commands exit status (which is a SHELL_STATUS) in ExitData. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Brendan Jackman <Brendan.Jackman@arm.com> Reviewed-by: Olivier Martin <olivier.martin@arm.com> Reviewed-by: Jaben Carsey <Jaben.carsey@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15180 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
fed3be946c
commit
5223c12135
|
@ -244,6 +244,9 @@ UefiMain (
|
|||
UINTN Size;
|
||||
EFI_HANDLE ConInHandle;
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *OldConIn;
|
||||
UINTN ExitDataSize;
|
||||
CHAR16 *ExitData;
|
||||
SHELL_STATUS ExitStatus;
|
||||
|
||||
if (PcdGet8(PcdShellSupportLevel) > 3) {
|
||||
return (EFI_UNSUPPORTED);
|
||||
|
@ -406,7 +409,7 @@ UefiMain (
|
|||
// Display the mapping
|
||||
//
|
||||
if (PcdGet8(PcdShellSupportLevel) >= 2 && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap) {
|
||||
Status = RunCommand(L"map");
|
||||
Status = RunCommand(L"map", NULL);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
}
|
||||
|
||||
|
@ -472,7 +475,11 @@ UefiMain (
|
|||
//
|
||||
// process the startup script or launch the called app.
|
||||
//
|
||||
Status = DoStartupScript(ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);
|
||||
Status = DoStartupScript(
|
||||
ShellInfoObject.ImageDevPath,
|
||||
ShellInfoObject.FileDevPath,
|
||||
&ExitStatus
|
||||
);
|
||||
}
|
||||
|
||||
if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit && !ShellCommandGetExit() && (PcdGet8(PcdShellSupportLevel) >= 3 || PcdGetBool(PcdShellForceConsole)) && !EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
|
||||
|
@ -505,6 +512,7 @@ UefiMain (
|
|||
//
|
||||
Status = DoShellPrompt();
|
||||
} while (!ShellCommandGetExit());
|
||||
ExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();
|
||||
}
|
||||
if (OldConIn != NULL && ConInHandle != NULL) {
|
||||
CloseSimpleTextInOnFile (gST->ConIn);
|
||||
|
@ -575,10 +583,29 @@ UefiMain (
|
|||
DEBUG_CODE(ShellInfoObject.ConsoleInfo = NULL;);
|
||||
}
|
||||
|
||||
if (ShellCommandGetExit()) {
|
||||
return ((EFI_STATUS)ShellCommandGetExitCode());
|
||||
// If the command exited with an error, we pass this error out in the ExitData
|
||||
// so that it can be retrieved by the EfiShellExecute function (which may
|
||||
// start the shell with gBS->StartImage)
|
||||
if (ExitStatus != SHELL_SUCCESS) {
|
||||
// Allocate a buffer for exit data to pass to gBS->Exit().
|
||||
// This buffer will contain the empty string immediately followed by
|
||||
// the shell's exit status. (The empty string is required by the UEFI spec)
|
||||
ExitDataSize = (sizeof (CHAR16) + sizeof (SHELL_STATUS));
|
||||
ExitData = AllocatePool (ExitDataSize);
|
||||
if (ExitData == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
ExitData[0] = '\0';
|
||||
// Use CopyMem to avoid alignment faults
|
||||
CopyMem ((ExitData + 1), &ExitStatus, sizeof (ExitStatus));
|
||||
|
||||
gBS->Exit (ImageHandle, EFI_ABORTED, ExitDataSize, ExitData);
|
||||
} else {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return (Status);
|
||||
|
||||
ASSERT (FALSE);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -872,13 +899,16 @@ ProcessCommandLine(
|
|||
@param ImagePath the path to the image for shell. first place to look for the startup script
|
||||
@param FilePath the path to the file for shell. second place to look for the startup script.
|
||||
|
||||
@param[out] ExitStatus The exit code of the script. Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS the variable is initialized.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DoStartupScript(
|
||||
EFI_DEVICE_PATH_PROTOCOL *ImagePath,
|
||||
EFI_DEVICE_PATH_PROTOCOL *FilePath
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -913,7 +943,7 @@ DoStartupScript(
|
|||
StrCat(FileStringPath, L" ");
|
||||
StrCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions);
|
||||
}
|
||||
Status = RunCommand(FileStringPath);
|
||||
Status = RunCommand(FileStringPath, ExitStatus);
|
||||
FreePool(FileStringPath);
|
||||
return (Status);
|
||||
|
||||
|
@ -990,7 +1020,13 @@ DoStartupScript(
|
|||
// If we got a file, run it
|
||||
//
|
||||
if (!EFI_ERROR(Status) && FileHandle != NULL) {
|
||||
Status = RunScriptFile (mStartupScript, FileHandle, L"", ShellInfoObject.NewShellParametersProtocol);
|
||||
Status = RunScriptFile (
|
||||
mStartupScript,
|
||||
FileHandle,
|
||||
L"",
|
||||
ShellInfoObject.NewShellParametersProtocol,
|
||||
ExitStatus
|
||||
);
|
||||
ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
|
||||
} else {
|
||||
FileStringPath = ShellFindFilePath(mStartupScript);
|
||||
|
@ -1001,7 +1037,13 @@ DoStartupScript(
|
|||
Status = EFI_SUCCESS;
|
||||
ASSERT(FileHandle == NULL);
|
||||
} else {
|
||||
Status = RunScriptFile(FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);
|
||||
Status = RunScriptFile(
|
||||
FileStringPath,
|
||||
NULL,
|
||||
L"",
|
||||
ShellInfoObject.NewShellParametersProtocol,
|
||||
ExitStatus
|
||||
);
|
||||
FreePool(FileStringPath);
|
||||
}
|
||||
}
|
||||
|
@ -1066,7 +1108,7 @@ DoShellPrompt (
|
|||
//
|
||||
if (!EFI_ERROR (Status)) {
|
||||
CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;
|
||||
Status = RunCommand(CmdLine);
|
||||
Status = RunCommand(CmdLine, NULL);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1326,6 +1368,9 @@ ShellConvertVariables (
|
|||
@param[in] StdIn The pointer to the Standard input.
|
||||
@param[in] StdOut The pointer to the Standard output.
|
||||
|
||||
@param[out] ExitStatus The exit code of the last command in the pipeline.
|
||||
Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS The split command is executed successfully.
|
||||
@retval other Some error occurs when executing the split command.
|
||||
**/
|
||||
|
@ -1334,7 +1379,8 @@ EFIAPI
|
|||
RunSplitCommand(
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
IN SHELL_FILE_HANDLE *StdIn,
|
||||
IN SHELL_FILE_HANDLE *StdOut
|
||||
IN SHELL_FILE_HANDLE *StdOut,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -1388,7 +1434,7 @@ RunSplitCommand(
|
|||
ASSERT(Split->SplitStdOut != NULL);
|
||||
InsertHeadList(&ShellInfoObject.SplitList.Link, &Split->Link);
|
||||
|
||||
Status = RunCommand(OurCommandLine);
|
||||
Status = RunCommand(OurCommandLine, NULL);
|
||||
|
||||
//
|
||||
// move the output from the first to the in to the second.
|
||||
|
@ -1403,7 +1449,7 @@ RunSplitCommand(
|
|||
ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);
|
||||
|
||||
if (!EFI_ERROR(Status)) {
|
||||
Status = RunCommand(NextCommandLine);
|
||||
Status = RunCommand(NextCommandLine, ExitStatus);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1695,7 +1741,9 @@ VerifySplit(
|
|||
/**
|
||||
Process a split based operation.
|
||||
|
||||
@param[in] CmdLine pointer to the command line to process
|
||||
@param[in] CmdLine Pointer to the command line to process
|
||||
@param[out] ExitStatus The exit status of the command. Ignored if NULL.
|
||||
Invalid if this function returns an error.
|
||||
|
||||
@retval EFI_SUCCESS The operation was successful
|
||||
@return an error occured.
|
||||
|
@ -1703,7 +1751,8 @@ VerifySplit(
|
|||
EFI_STATUS
|
||||
EFIAPI
|
||||
ProcessNewSplitCommandLine(
|
||||
IN CONST CHAR16 *CmdLine
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
)
|
||||
{
|
||||
SPLIT_LIST *Split;
|
||||
|
@ -1724,9 +1773,14 @@ ProcessNewSplitCommandLine(
|
|||
}
|
||||
|
||||
if (Split == NULL) {
|
||||
Status = RunSplitCommand(CmdLine, NULL, NULL);
|
||||
Status = RunSplitCommand(CmdLine, NULL, NULL, ExitStatus);
|
||||
} else {
|
||||
Status = RunSplitCommand(CmdLine, Split->SplitStdIn, Split->SplitStdOut);
|
||||
Status = RunSplitCommand(
|
||||
CmdLine,
|
||||
Split->SplitStdIn,
|
||||
Split->SplitStdOut,
|
||||
ExitStatus
|
||||
);
|
||||
}
|
||||
if (EFI_ERROR(Status)) {
|
||||
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, CmdLine);
|
||||
|
@ -1901,6 +1955,8 @@ ProcessCommandLineToFinal(
|
|||
@param[in] FirstParameter the first parameter on the command line
|
||||
@param[in] ParamProtocol the shell parameters protocol pointer
|
||||
|
||||
@param[out] ExitStatus The exit code of the command. Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS The command was completed.
|
||||
@retval EFI_ABORTED The command's operation was aborted.
|
||||
**/
|
||||
|
@ -1909,7 +1965,8 @@ EFIAPI
|
|||
RunInternalCommand(
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
IN CHAR16 *FirstParameter,
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,
|
||||
OUT SHELL_STATUS *ExitStatus OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -1936,6 +1993,9 @@ RunInternalCommand(
|
|||
if (LastError) {
|
||||
SetLastError(CommandReturnedStatus);
|
||||
}
|
||||
if (ExitStatus != NULL) {
|
||||
*ExitStatus = CommandReturnedStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Pass thru the exitcode from the app.
|
||||
|
@ -1990,6 +2050,9 @@ RunInternalCommand(
|
|||
@param[in] FirstParameter the first parameter on the command line
|
||||
@param[in] ParamProtocol the shell parameters protocol pointer
|
||||
|
||||
@param[out] ExitStatus The exit code of the command or file.
|
||||
Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS The command was completed.
|
||||
@retval EFI_ABORTED The command's operation was aborted.
|
||||
**/
|
||||
|
@ -1999,13 +2062,14 @@ RunCommandOrFile(
|
|||
IN SHELL_OPERATION_TYPES Type,
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
IN CHAR16 *FirstParameter,
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS StatusCode;
|
||||
CHAR16 *CommandWithPath;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevPath;
|
||||
SHELL_STATUS CalleeExitStatus;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
CommandWithPath = NULL;
|
||||
|
@ -2013,7 +2077,12 @@ RunCommandOrFile(
|
|||
|
||||
switch (Type) {
|
||||
case Internal_Command:
|
||||
Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol);
|
||||
Status = RunInternalCommand(
|
||||
CmdLine,
|
||||
FirstParameter,
|
||||
ParamProtocol,
|
||||
&CalleeExitStatus
|
||||
);
|
||||
break;
|
||||
case Script_File_Name:
|
||||
case Efi_Application:
|
||||
|
@ -2048,7 +2117,13 @@ RunCommandOrFile(
|
|||
}
|
||||
switch (Type) {
|
||||
case Script_File_Name:
|
||||
Status = RunScriptFile (CommandWithPath, NULL, CmdLine, ParamProtocol);
|
||||
Status = RunScriptFile (
|
||||
CommandWithPath,
|
||||
NULL,
|
||||
CmdLine,
|
||||
ParamProtocol,
|
||||
&CalleeExitStatus
|
||||
);
|
||||
break;
|
||||
case Efi_Application:
|
||||
//
|
||||
|
@ -2068,7 +2143,8 @@ RunCommandOrFile(
|
|||
DevPath,
|
||||
CmdLine,
|
||||
NULL,
|
||||
&StatusCode
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
SHELL_FREE_NON_NULL(DevPath);
|
||||
|
@ -2076,7 +2152,8 @@ RunCommandOrFile(
|
|||
//
|
||||
// Update last error status.
|
||||
//
|
||||
SetLastError((SHELL_STATUS) StatusCode);
|
||||
// Status is an EFI_STATUS. Clear top bit to convert to SHELL_STATUS
|
||||
SetLastError((SHELL_STATUS) (Status & (~MAX_BIT)));
|
||||
break;
|
||||
default:
|
||||
//
|
||||
|
@ -2094,6 +2171,10 @@ RunCommandOrFile(
|
|||
|
||||
SHELL_FREE_NON_NULL(CommandWithPath);
|
||||
|
||||
if (ExitStatus != NULL) {
|
||||
*ExitStatus = CalleeExitStatus;
|
||||
}
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
@ -2105,16 +2186,20 @@ RunCommandOrFile(
|
|||
@param[in] FirstParameter the first parameter on the command line.
|
||||
@param[in] ParamProtocol the shell parameters protocol pointer
|
||||
|
||||
@param[out] ExitStatus The exit code of the command or file.
|
||||
Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS The command was completed.
|
||||
@retval EFI_ABORTED The command's operation was aborted.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetupAndRunCommandOrFile(
|
||||
IN SHELL_OPERATION_TYPES Type,
|
||||
IN CHAR16 *CmdLine,
|
||||
IN CHAR16 *FirstParameter,
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
|
||||
IN SHELL_OPERATION_TYPES Type,
|
||||
IN CHAR16 *CmdLine,
|
||||
IN CHAR16 *FirstParameter,
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -2133,7 +2218,13 @@ SetupAndRunCommandOrFile(
|
|||
// Now run the command, script, or application
|
||||
//
|
||||
if (!EFI_ERROR(Status)) {
|
||||
Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol);
|
||||
Status = RunCommandOrFile(
|
||||
Type,
|
||||
CmdLine,
|
||||
FirstParameter,
|
||||
ParamProtocol,
|
||||
ExitStatus
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2158,6 +2249,7 @@ SetupAndRunCommandOrFile(
|
|||
command or dispatch an external application.
|
||||
|
||||
@param[in] CmdLine The command line to parse.
|
||||
@param[out] ExitStatus The exit code of the command. Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS The command was completed.
|
||||
@retval EFI_ABORTED The command's operation was aborted.
|
||||
|
@ -2165,7 +2257,8 @@ SetupAndRunCommandOrFile(
|
|||
EFI_STATUS
|
||||
EFIAPI
|
||||
RunCommand(
|
||||
IN CONST CHAR16 *CmdLine
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -2207,7 +2300,7 @@ RunCommand(
|
|||
// We dont do normal processing with a split command line (output from one command input to another)
|
||||
//
|
||||
if (ContainsSplit(CleanOriginal)) {
|
||||
Status = ProcessNewSplitCommandLine(CleanOriginal);
|
||||
Status = ProcessNewSplitCommandLine(CleanOriginal, ExitStatus);
|
||||
SHELL_FREE_NON_NULL(CleanOriginal);
|
||||
return (Status);
|
||||
}
|
||||
|
@ -2233,7 +2326,13 @@ RunCommand(
|
|||
case Internal_Command:
|
||||
case Script_File_Name:
|
||||
case Efi_Application:
|
||||
Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol);
|
||||
Status = SetupAndRunCommandOrFile(
|
||||
Type,
|
||||
CleanOriginal,
|
||||
FirstParameter,
|
||||
ShellInfoObject.NewShellParametersProtocol,
|
||||
ExitStatus
|
||||
);
|
||||
break;
|
||||
default:
|
||||
//
|
||||
|
@ -2288,13 +2387,16 @@ IsValidCommandName(
|
|||
@param[in] Handle The handle to the already opened file.
|
||||
@param[in] Name The name of the script file.
|
||||
|
||||
@param[out] ExitStatus The exit code of the script. Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS the script completed sucessfully
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RunScriptFileHandle (
|
||||
IN SHELL_FILE_HANDLE Handle,
|
||||
IN CONST CHAR16 *Name
|
||||
IN SHELL_FILE_HANDLE Handle,
|
||||
IN CONST CHAR16 *Name,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -2310,6 +2412,7 @@ RunScriptFileHandle (
|
|||
CONST CHAR16 *CurDir;
|
||||
UINTN LineCount;
|
||||
CHAR16 LeString[50];
|
||||
SHELL_STATUS CalleeExitStatus = SHELL_SUCCESS;
|
||||
|
||||
ASSERT(!ShellCommandGetScriptExit());
|
||||
|
||||
|
@ -2495,7 +2598,7 @@ RunScriptFileHandle (
|
|||
//
|
||||
PreCommandEchoState = ShellCommandGetEchoState();
|
||||
ShellCommandSetEchoState(FALSE);
|
||||
Status = RunCommand(CommandLine3+1);
|
||||
Status = RunCommand(CommandLine3+1, NULL);
|
||||
|
||||
//
|
||||
// If command was "@echo -off" or "@echo -on" then don't restore echo state
|
||||
|
@ -2517,7 +2620,7 @@ RunScriptFileHandle (
|
|||
}
|
||||
ShellPrintEx(-1, -1, L"%s\r\n", CommandLine2);
|
||||
}
|
||||
Status = RunCommand(CommandLine3);
|
||||
Status = RunCommand(CommandLine3, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2525,7 +2628,8 @@ RunScriptFileHandle (
|
|||
//
|
||||
// ShellCommandGetExitCode() always returns a UINT64
|
||||
//
|
||||
UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellCommandGetExitCode());
|
||||
CalleeExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();
|
||||
UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", CalleeExitStatus);
|
||||
DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
|
||||
InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
|
||||
|
||||
|
@ -2537,9 +2641,11 @@ RunScriptFileHandle (
|
|||
break;
|
||||
}
|
||||
if (EFI_ERROR(Status)) {
|
||||
CalleeExitStatus = (SHELL_STATUS) Status;
|
||||
break;
|
||||
}
|
||||
if (ShellCommandGetExit()) {
|
||||
CalleeExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2571,6 +2677,11 @@ RunScriptFileHandle (
|
|||
if (ShellCommandGetCurrentScriptFile()==NULL) {
|
||||
ShellCommandSetEchoState(PreScriptEchoState);
|
||||
}
|
||||
|
||||
if (ExitStatus != NULL) {
|
||||
*ExitStatus = CalleeExitStatus;
|
||||
}
|
||||
|
||||
return (EFI_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -2582,15 +2693,18 @@ RunScriptFileHandle (
|
|||
@param[in] CmdLine the command line to run.
|
||||
@param[in] ParamProtocol the shell parameters protocol pointer
|
||||
|
||||
@param[out] ExitStatus The exit code of the script. Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS the script completed sucessfully
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RunScriptFile (
|
||||
IN CONST CHAR16 *ScriptPath,
|
||||
IN SHELL_FILE_HANDLE Handle OPTIONAL,
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
|
||||
IN CONST CHAR16 *ScriptPath,
|
||||
IN SHELL_FILE_HANDLE Handle OPTIONAL,
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -2617,7 +2731,7 @@ RunScriptFile (
|
|||
//
|
||||
// run it
|
||||
//
|
||||
Status = RunScriptFileHandle(FileHandle, ScriptPath);
|
||||
Status = RunScriptFileHandle(FileHandle, ScriptPath, ExitStatus);
|
||||
|
||||
//
|
||||
// now close the file
|
||||
|
@ -2625,7 +2739,7 @@ RunScriptFile (
|
|||
ShellCloseFile(&FileHandle);
|
||||
}
|
||||
} else {
|
||||
Status = RunScriptFileHandle(Handle, ScriptPath);
|
||||
Status = RunScriptFileHandle(Handle, ScriptPath, ExitStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -230,14 +230,17 @@ ProcessCommandLine(
|
|||
|
||||
@param[in] ImagePath The path to the image for shell. The first place to look for the startup script.
|
||||
@param[in] FilePath The path to the file for shell. The second place to look for the startup script.
|
||||
@param[out] ExitStatus The exit code of the script. Ignored if NULL.
|
||||
Invalid when this function returns an error.
|
||||
|
||||
@retval EFI_SUCCESS The variable is initialized.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DoStartupScript(
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -282,7 +285,8 @@ AddLineToCommandHistory(
|
|||
|
||||
This will determine if the command line represents an internal shell command or dispatch an external application.
|
||||
|
||||
@param[in] CmdLine the command line to parse
|
||||
@param[in] CmdLine the command line to parse
|
||||
@param[out] ExitStatus The exit status of the command. Ignored if NULL.
|
||||
|
||||
@retval EFI_SUCCESS the command was completed
|
||||
@retval EFI_ABORTED the command's operation was aborted
|
||||
|
@ -290,7 +294,8 @@ AddLineToCommandHistory(
|
|||
EFI_STATUS
|
||||
EFIAPI
|
||||
RunCommand(
|
||||
IN CONST CHAR16 *CmdLine
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -314,13 +319,17 @@ IsValidCommandName(
|
|||
@param[in] Handle The handle to the already opened file.
|
||||
@param[in] Name The name of the script file.
|
||||
|
||||
@param[out] ExitStatus The exit code of the script. Ignored if NULL.
|
||||
Invalid when this function returns an error.
|
||||
|
||||
@retval EFI_SUCCESS the script completed sucessfully
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RunScriptFileHandle (
|
||||
IN SHELL_FILE_HANDLE Handle,
|
||||
IN CONST CHAR16 *Name
|
||||
IN SHELL_FILE_HANDLE Handle,
|
||||
IN CONST CHAR16 *Name,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -331,17 +340,20 @@ RunScriptFileHandle (
|
|||
@param[in] CmdLine the command line to run.
|
||||
@param[in] ParamProtocol the shell parameters protocol pointer
|
||||
|
||||
@param[out] ExitStatus The exit code of the script. Ignored if NULL.
|
||||
Invalid when this function returns an error.
|
||||
|
||||
@retval EFI_SUCCESS the script completed sucessfully
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RunScriptFile (
|
||||
IN CONST CHAR16 *ScriptPath,
|
||||
IN SHELL_FILE_HANDLE Handle OPTIONAL,
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
|
||||
IN CONST CHAR16 *ScriptPath,
|
||||
IN SHELL_FILE_HANDLE Handle OPTIONAL,
|
||||
IN CONST CHAR16 *CmdLine,
|
||||
IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,
|
||||
OUT SHELL_STATUS *ExitStatus
|
||||
);
|
||||
|
||||
|
||||
#endif //_SHELL_INTERNAL_HEADER_
|
||||
|
||||
|
|
|
@ -1358,6 +1358,9 @@ EfiShellEnablePageBreak (
|
|||
is NULL, then the current shell environment is used.
|
||||
@param StatusCode Points to the status code returned by the command.
|
||||
|
||||
@param[out] ExitDataSize ExitDataSize as returned from gBS->StartImage
|
||||
@param[out] ExitData ExitData as returned from gBS->StartImage
|
||||
|
||||
@retval EFI_SUCCESS The command executed successfully. The status code
|
||||
returned by the command is pointed to by StatusCode.
|
||||
@retval EFI_INVALID_PARAMETER The parameters are invalid.
|
||||
|
@ -1371,7 +1374,8 @@ InternalShellExecuteDevicePath(
|
|||
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
IN CONST CHAR16 *CommandLine OPTIONAL,
|
||||
IN CONST CHAR16 **Environment OPTIONAL,
|
||||
OUT EFI_STATUS *StatusCode OPTIONAL
|
||||
OUT UINTN *ExitDataSize OPTIONAL,
|
||||
OUT CHAR16 **ExitData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
@ -1379,6 +1383,16 @@ InternalShellExecuteDevicePath(
|
|||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||
LIST_ENTRY OrigEnvs;
|
||||
EFI_SHELL_PARAMETERS_PROTOCOL ShellParamsProtocol;
|
||||
UINTN InternalExitDataSize;
|
||||
UINTN *ExitDataSizePtr;
|
||||
|
||||
// ExitDataSize is not OPTIONAL for gBS->BootServices, provide somewhere for
|
||||
// it to be dumped if the caller doesn't want it.
|
||||
if (ExitData == NULL) {
|
||||
ExitDataSizePtr = &InternalExitDataSize;
|
||||
} else {
|
||||
ExitDataSizePtr = ExitDataSize;
|
||||
}
|
||||
|
||||
if (ParentImageHandle == NULL) {
|
||||
return (EFI_INVALID_PARAMETER);
|
||||
|
@ -1445,14 +1459,14 @@ InternalShellExecuteDevicePath(
|
|||
///@todo initialize and install ShellInterface protocol on the new image for compatibility if - PcdGetBool(PcdShellSupportOldProtocols)
|
||||
|
||||
//
|
||||
// now start the image and if the caller wanted the return code pass it to them...
|
||||
// now start the image, passing up exit data if the caller requested it
|
||||
//
|
||||
if (!EFI_ERROR(Status)) {
|
||||
if (StatusCode != NULL) {
|
||||
*StatusCode = gBS->StartImage(NewHandle, NULL, NULL);
|
||||
} else {
|
||||
Status = gBS->StartImage(NewHandle, NULL, NULL);
|
||||
}
|
||||
Status = gBS->StartImage(
|
||||
NewHandle,
|
||||
ExitDataSizePtr,
|
||||
ExitData
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1523,6 +1537,8 @@ EfiShellExecute(
|
|||
CHAR16 *Temp;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevPath;
|
||||
UINTN Size;
|
||||
UINTN ExitDataSize;
|
||||
CHAR16 *ExitData;
|
||||
|
||||
if ((PcdGet8(PcdShellSupportLevel) < 1)) {
|
||||
return (EFI_UNSUPPORTED);
|
||||
|
@ -1550,7 +1566,33 @@ EfiShellExecute(
|
|||
DevPath,
|
||||
Temp,
|
||||
(CONST CHAR16**)Environment,
|
||||
StatusCode);
|
||||
&ExitDataSize,
|
||||
&ExitData);
|
||||
|
||||
if (Status == EFI_ABORTED) {
|
||||
// If the command exited with an error, the shell should put the exit
|
||||
// status in ExitData, preceded by a null-terminated string.
|
||||
ASSERT (ExitDataSize == StrSize (ExitData) + sizeof (SHELL_STATUS));
|
||||
|
||||
if (StatusCode != NULL) {
|
||||
// Skip the null-terminated string
|
||||
ExitData += StrLen (ExitData) + 1;
|
||||
|
||||
// Use CopyMem to avoid alignment faults
|
||||
CopyMem (StatusCode, ExitData, sizeof (SHELL_STATUS));
|
||||
|
||||
// Convert from SHELL_STATUS to EFI_STATUS
|
||||
// EFI_STATUSes have top bit set when they are errors.
|
||||
// (See UEFI Spec Appendix D)
|
||||
if (*StatusCode != SHELL_SUCCESS) {
|
||||
*StatusCode = (EFI_STATUS) *StatusCode | MAX_BIT;
|
||||
}
|
||||
}
|
||||
FreePool (ExitData);
|
||||
Status = EFI_SUCCESS;
|
||||
} else if ((StatusCode != NULL) && !EFI_ERROR(Status)) {
|
||||
*StatusCode = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// de-allocate and return
|
||||
|
|
|
@ -443,6 +443,9 @@ EfiShellEnablePageBreak (
|
|||
variables with the format 'x=y', where x is the
|
||||
environment variable name and y is the value. If this
|
||||
is NULL, then the current shell environment is used.
|
||||
@param[out] ExitDataSize ExitDataSize as returned from gBS->StartImage
|
||||
@param[out] ExitData ExitData as returned from gBS->StartImage
|
||||
|
||||
@param StatusCode Points to the status code returned by the command.
|
||||
|
||||
@retval EFI_SUCCESS The command executed successfully. The status code
|
||||
|
@ -458,7 +461,8 @@ InternalShellExecuteDevicePath(
|
|||
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
IN CONST CHAR16 *CommandLine OPTIONAL,
|
||||
IN CONST CHAR16 **Environment OPTIONAL,
|
||||
OUT EFI_STATUS *StatusCode OPTIONAL
|
||||
OUT UINTN *ExitDataSize OPTIONAL,
|
||||
OUT CHAR16 **ExitData OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue