]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Application/Shell/Shell.c
ShellPkg: Use a local variable to cache the pointer.
[mirror_edk2.git] / ShellPkg / Application / Shell / Shell.c
index 97b8c8d6fbee39a890b6b48216fec8d0dd723a88..47b3118ea701cb414af611f9dbcbe420ced5fd1a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This is THE shell (application)\r
 \r
-  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
   (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -33,6 +33,7 @@ SHELL_INFO ShellInfoObject = {
       0,\r
       0,\r
       0,\r
+      0,\r
       0\r
     }},\r
     0,\r
@@ -69,6 +70,9 @@ SHELL_INFO ShellInfoObject = {
 STATIC CONST CHAR16 mScriptExtension[]      = L".NSH";\r
 STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";\r
 STATIC CONST CHAR16 mStartupScript[]        = L"startup.nsh";\r
+CONST CHAR16 mNoNestingEnvVarName[]         = L"nonesting";\r
+CONST CHAR16 mNoNestingTrue[]               = L"True";\r
+CONST CHAR16 mNoNestingFalse[]              = L"False";\r
 \r
 /**\r
   Cleans off leading and trailing spaces and tabs.\r
@@ -441,6 +445,8 @@ UefiMain (
     Status = CommandInit();\r
     ASSERT_EFI_ERROR(Status);\r
 \r
+    Status = ShellInitEnvVarList ();\r
+\r
     //\r
     // Check the command line\r
     //\r
@@ -456,6 +462,29 @@ UefiMain (
       Status = ShellCommandCreateInitialMappingsAndPaths();\r
     }\r
 \r
+    //\r
+    // Set the environment variable for nesting support\r
+    //\r
+    Size = 0;\r
+    TempString = NULL;\r
+    if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {\r
+      //\r
+      // No change.  require nesting in Shell Protocol Execute()\r
+      //\r
+      StrnCatGrow(&TempString,\r
+                  &Size,\r
+                  L"False",\r
+                  0);\r
+    } else {\r
+      StrnCatGrow(&TempString,\r
+                  &Size,\r
+                  mNoNestingTrue,\r
+                  0);\r
+    }\r
+    Status = InternalEfiShellSetEnv(mNoNestingEnvVarName, TempString, TRUE);\r
+    SHELL_FREE_NON_NULL(TempString);\r
+    Size = 0;\r
+\r
     //\r
     // save the device path for the loaded image and the device path for the filepath (under loaded image)\r
     // These are where to look for the startup.nsh file\r
@@ -675,6 +704,8 @@ FreeResources:
     DEBUG_CODE(ShellInfoObject.ConsoleInfo = NULL;);\r
   }\r
 \r
+  ShellFreeEnvVarList ();\r
+\r
   if (ShellCommandGetExit()) {\r
     return ((EFI_STATUS)ShellCommandGetExitCode());\r
   }\r
@@ -891,6 +922,7 @@ ProcessCommandLine(
   ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion    = FALSE;\r
   ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay        = FALSE;\r
   ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit         = FALSE;\r
+  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest       = FALSE;\r
   ShellInfoObject.ShellInitSettings.Delay = 5;\r
 \r
   //\r
@@ -950,6 +982,13 @@ ProcessCommandLine(
                                  ) == 0) {\r
       ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion    = TRUE;\r
     }\r
+    else if (UnicodeCollation->StriColl (\r
+                                 UnicodeCollation,\r
+                                 L"-nonest",\r
+                                 CurrentArg\r
+                                 ) == 0) {\r
+      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest       = TRUE;\r
+    }\r
     else if (UnicodeCollation->StriColl (\r
                                  UnicodeCollation,\r
                                  L"-delay",\r
@@ -1205,6 +1244,7 @@ DoShellPrompt (
   CONST CHAR16  *CurDir;\r
   UINTN         BufferSize;\r
   EFI_STATUS    Status;\r
+  LIST_ENTRY    OldBufferList;\r
 \r
   CurDir  = NULL;\r
 \r
@@ -1218,6 +1258,7 @@ DoShellPrompt (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
+  SaveBufferList(&OldBufferList);\r
   CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv(L"cwd");\r
 \r
   //\r
@@ -1247,6 +1288,7 @@ DoShellPrompt (
   //\r
   // Done with this command\r
   //\r
+  RestoreBufferList(&OldBufferList);\r
   FreePool (CmdLine);\r
   return Status;\r
 }\r
@@ -1276,6 +1318,36 @@ AddBufferToFreeList(
   return (Buffer);\r
 }\r
 \r
+\r
+/**\r
+  Create a new buffer list and stores the old one to OldBufferList \r
+\r
+  @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.\r
+**/\r
+VOID\r
+SaveBufferList (\r
+  OUT LIST_ENTRY     *OldBufferList\r
+  )\r
+{\r
+  CopyMem (OldBufferList, &ShellInfoObject.BufferToFreeList.Link, sizeof (LIST_ENTRY));\r
+  InitializeListHead (&ShellInfoObject.BufferToFreeList.Link);\r
+}\r
+\r
+/**\r
+  Restore previous nodes into BufferToFreeList .\r
+\r
+  @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.\r
+**/\r
+VOID\r
+RestoreBufferList (\r
+  IN OUT LIST_ENTRY     *OldBufferList\r
+  )\r
+{\r
+  FreeBufferList (&ShellInfoObject.BufferToFreeList);\r
+  CopyMem (&ShellInfoObject.BufferToFreeList.Link, OldBufferList, sizeof (LIST_ENTRY));\r
+}\r
+\r
+\r
 /**\r
   Add a buffer to the Line History List\r
 \r
@@ -1291,7 +1363,7 @@ AddLineToCommandHistory(
   BUFFER_LIST *Walker;\r
   UINT16       MaxHistoryCmdCount;\r
   UINT16       Count;\r
-  \r
+\r
   Count = 0;\r
   MaxHistoryCmdCount = PcdGet16(PcdShellMaxHistoryCommandCount);\r
   \r
@@ -2419,7 +2491,7 @@ SetupAndRunCommandOrFile(
   IN   CHAR16                         *CmdLine,\r
   IN   CHAR16                         *FirstParameter,\r
   IN   EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol,\r
-  OUT EFI_STATUS                    *CommandStatus\r
+  OUT EFI_STATUS                      *CommandStatus\r
 )\r
 {\r
   EFI_STATUS                Status;\r
@@ -2427,6 +2499,7 @@ SetupAndRunCommandOrFile(
   SHELL_FILE_HANDLE         OriginalStdOut;\r
   SHELL_FILE_HANDLE         OriginalStdErr;\r
   SYSTEM_TABLE_INFO         OriginalSystemTableInfo;\r
+  CONST SCRIPT_FILE         *ConstScriptFile;\r
 \r
   //\r
   // Update the StdIn, StdOut, and StdErr for redirection to environment variables, files, etc... unicode and ASCII\r
@@ -2446,7 +2519,12 @@ SetupAndRunCommandOrFile(
   // Now print errors\r
   //\r
   if (EFI_ERROR(Status)) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));\r
+    ConstScriptFile = ShellCommandGetCurrentScriptFile();\r
+    if (ConstScriptFile == NULL || ConstScriptFile->CurrentCommand == NULL) {\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));\r
+    } else {\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR_SCRIPT), ShellInfoObject.HiiHandle, (VOID*)(Status), ConstScriptFile->CurrentCommand->Line);\r
+    }\r
   }\r
 \r
   //\r
@@ -2661,6 +2739,7 @@ RunScriptFileHandle (
   CONST CHAR16        *CurDir;\r
   UINTN               LineCount;\r
   CHAR16              LeString[50];\r
+  LIST_ENTRY          OldBufferList;\r
 \r
   ASSERT(!ShellCommandGetScriptExit());\r
 \r
@@ -2763,6 +2842,8 @@ RunScriptFileHandle (
               PrintBuffSize/sizeof(CHAR16) - 1\r
               );\r
 \r
+    SaveBufferList(&OldBufferList);\r
+\r
     //\r
     // NULL out comments\r
     //\r
@@ -2897,15 +2978,19 @@ RunScriptFileHandle (
 \r
           ShellCommandRegisterExit(FALSE, 0);\r
           Status = EFI_SUCCESS;\r
+          RestoreBufferList(&OldBufferList);\r
           break;\r
         }\r
         if (ShellGetExecutionBreakFlag()) {\r
+          RestoreBufferList(&OldBufferList);\r
           break;\r
         }\r
         if (EFI_ERROR(Status)) {\r
+          RestoreBufferList(&OldBufferList);\r
           break;\r
         }\r
         if (ShellCommandGetExit()) {\r
+          RestoreBufferList(&OldBufferList);\r
           break;\r
         }\r
       }\r
@@ -2924,6 +3009,7 @@ RunScriptFileHandle (
         NewScriptFile->CurrentCommand->Reset = TRUE;\r
       }\r
     }\r
+    RestoreBufferList(&OldBufferList);\r
   }\r
 \r
 \r