ShellPkg: Do not mix status when executing a command

The function InternalShellExecuteDevicePath() did not differentiate an error occuring during the preparation of an image and an error occurring during its execution.

A use case of the issue was when a EFI application was called in a EFI Shell script. If the EFI application was returning an error then the NSH script stopped its execution. While the EFI Shell specification says the script should continue its execution (see 4.2 Error Handling).

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-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@15523 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Olivier Martin 2014-05-13 21:16:42 +00:00 committed by jcarsey
parent 93e8d03cd1
commit cd39fe082c
3 changed files with 14 additions and 7 deletions

View File

@ -2231,6 +2231,7 @@ RunCommandOrFile(
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_STATUS StartStatus;
CHAR16 *CommandWithPath; CHAR16 *CommandWithPath;
EFI_DEVICE_PATH_PROTOCOL *DevPath; EFI_DEVICE_PATH_PROTOCOL *DevPath;
SHELL_STATUS CalleeExitStatus; SHELL_STATUS CalleeExitStatus;
@ -2308,6 +2309,7 @@ RunCommandOrFile(
DevPath, DevPath,
CmdLine, CmdLine,
NULL, NULL,
&StartStatus,
NULL, NULL,
NULL NULL
); );
@ -2317,7 +2319,7 @@ RunCommandOrFile(
if(EFI_ERROR (Status)) { if(EFI_ERROR (Status)) {
CalleeExitStatus = (SHELL_STATUS) (Status & (~MAX_BIT)); CalleeExitStatus = (SHELL_STATUS) (Status & (~MAX_BIT));
} else { } else {
CalleeExitStatus = SHELL_SUCCESS; CalleeExitStatus = (SHELL_STATUS) StartStatus;
} }
// //

View File

@ -1386,11 +1386,13 @@ InternalShellExecuteDevicePath(
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CONST CHAR16 *CommandLine OPTIONAL, IN CONST CHAR16 *CommandLine OPTIONAL,
IN CONST CHAR16 **Environment OPTIONAL, IN CONST CHAR16 **Environment OPTIONAL,
OUT EFI_STATUS *StartImageStatus OPTIONAL,
OUT UINTN *ExitDataSize OPTIONAL, OUT UINTN *ExitDataSize OPTIONAL,
OUT CHAR16 **ExitData OPTIONAL OUT CHAR16 **ExitData OPTIONAL
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_STATUS StartStatus;
EFI_STATUS CleanupStatus; EFI_STATUS CleanupStatus;
EFI_HANDLE NewHandle; EFI_HANDLE NewHandle;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
@ -1504,11 +1506,14 @@ InternalShellExecuteDevicePath(
// now start the image, passing up exit data if the caller requested it // now start the image, passing up exit data if the caller requested it
// //
if (!EFI_ERROR(Status)) { if (!EFI_ERROR(Status)) {
Status = gBS->StartImage( StartStatus = gBS->StartImage(
NewHandle, NewHandle,
ExitDataSizePtr, ExitDataSizePtr,
ExitData ExitData
); );
if (StartImageStatus != NULL) {
*StartImageStatus = StartStatus;
}
CleanupStatus = gBS->UninstallProtocolInterface( CleanupStatus = gBS->UninstallProtocolInterface(
NewHandle, NewHandle,
@ -1620,6 +1625,7 @@ EfiShellExecute(
DevPath, DevPath,
Temp, Temp,
(CONST CHAR16**)Environment, (CONST CHAR16**)Environment,
StatusCode,
&ExitDataSize, &ExitDataSize,
&ExitData); &ExitData);
@ -1644,8 +1650,6 @@ EfiShellExecute(
} }
FreePool (ExitData); FreePool (ExitData);
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
} else if ((StatusCode != NULL) && !EFI_ERROR(Status)) {
*StatusCode = EFI_SUCCESS;
} }
// //

View File

@ -459,6 +459,7 @@ InternalShellExecuteDevicePath(
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN CONST CHAR16 *CommandLine OPTIONAL, IN CONST CHAR16 *CommandLine OPTIONAL,
IN CONST CHAR16 **Environment OPTIONAL, IN CONST CHAR16 **Environment OPTIONAL,
OUT EFI_STATUS *StartImageStatus OPTIONAL,
OUT UINTN *ExitDataSize OPTIONAL, OUT UINTN *ExitDataSize OPTIONAL,
OUT CHAR16 **ExitData OPTIONAL OUT CHAR16 **ExitData OPTIONAL
); );