https://git.reactos.org/?p=reactos.git;a=commitdiff;h=26ff2c8ef3ca97ab960be…
commit 26ff2c8ef3ca97ab960be45b0005c93090e08cb3
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Nov 18 23:41:31 2017 +0100
[CMD] Fix the errorlevel value set by the EXIT command, and when a batch file has run.
CORE-10495 CORE-13672
- Fix the behaviour of the EXIT command, where it set the last errorlevel
value ONLY when it was called with the /b switch and otherwise kept the
ambient one, instead of always using the value that the user specified
on the command-line.
- When a batch file has terminated, make the Batch() helper returning the
errorlevel value so that, when the batch file has been started with the
CALL command, CALL can in turn set the correct errorlevel value.
Verified with respect to Windows' cmd.exe.
---
base/shell/cmd/batch.c | 6 +++++-
base/shell/cmd/internal.c | 29 +++++++++++++++++++++--------
2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/base/shell/cmd/batch.c b/base/shell/cmd/batch.c
index bf36ddb610..148943a990 100644
--- a/base/shell/cmd/batch.c
+++ b/base/shell/cmd/batch.c
@@ -299,7 +299,8 @@ INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
* return until this context has been exited */
new.prev = bc;
/* copy some fields in the new structure if it is the same file */
- if (same_fn) {
+ if (same_fn)
+ {
new.mem = bc->mem;
new.memsize = bc->memsize;
new.mempos = 0;
@@ -366,6 +367,9 @@ INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
FreeCommand(Cmd);
}
+ /* Always return the current errorlevel */
+ ret = nErrorLevel;
+
TRACE ("Batch: returns TRUE\n");
fc = saved_fc;
diff --git a/base/shell/cmd/internal.c b/base/shell/cmd/internal.c
index 4830660bbc..fc05119829 100644
--- a/base/shell/cmd/internal.c
+++ b/base/shell/cmd/internal.c
@@ -514,26 +514,39 @@ INT CommandExit(LPTSTR param)
if (!_tcsncmp(param, _T("/?"), 2))
{
ConOutResPaging(TRUE, STRING_EXIT_HELP);
- /* Just make sure */
+
+ /* Just make sure we don't exit */
bExit = FALSE;
- /* Don't exit */
return 0;
}
- if (bc != NULL && _tcsnicmp(param, _T("/b"), 2) == 0)
+ if (_tcsnicmp(param, _T("/b"), 2) == 0)
{
param += 2;
- while (_istspace(*param))
- param++;
- if (_istdigit(*param))
- nErrorLevel = _ttoi(param);
- ExitBatch();
+
+ /*
+ * If a current batch file is running, exit it,
+ * otherwise exit this command interpreter instance.
+ */
+ if (bc)
+ ExitBatch();
+ else
+ bExit = TRUE;
}
else
{
+ /* Exit this command interpreter instance */
bExit = TRUE;
}
+ /* Search for an optional exit code */
+ while (_istspace(*param))
+ param++;
+
+ /* Set the errorlevel to the exit code */
+ if (_istdigit(*param))
+ nErrorLevel = _ttoi(param);
+
return 0;
}
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=56a19b1439effc8a3990f…
commit 56a19b1439effc8a3990f97ff9241379d55a07cb
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Nov 18 20:50:50 2017 +0100
[CMD] ExecutePipeline() returns the last error level (set to process exit code).
CORE-13974
This should fix situations where (for example):
command_1 | command_2 && echo Succeeded
should *NOT* run "echo Succeeded" if any of the command_1 or command_2 has
failed.
This also makes the ExecutePipeline() function on par with the other
"ExecuteXXX()" helpers.
Problem diagnosed by Doug Lyons; patch inspired by contributor 'cagey45'.
---
base/shell/cmd/cmd.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/base/shell/cmd/cmd.c b/base/shell/cmd/cmd.c
index e6c9bec785..549f10d59e 100644
--- a/base/shell/cmd/cmd.c
+++ b/base/shell/cmd/cmd.c
@@ -636,7 +636,7 @@ ExecuteAsync(PARSED_COMMAND *Cmd)
return prci.hProcess;
}
-static VOID
+static INT
ExecutePipeline(PARSED_COMMAND *Cmd)
{
#ifdef FEATURE_REDIRECTION
@@ -708,7 +708,7 @@ ExecutePipeline(PARSED_COMMAND *Cmd)
while (--nProcesses >= 0)
CloseHandle(hProcess[nProcesses]);
- return;
+ return nErrorLevel;
failed:
if (hInput)
@@ -721,6 +721,8 @@ failed:
SetStdHandle(STD_INPUT_HANDLE, hOldConIn);
SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut);
#endif
+
+ return nErrorLevel;
}
INT
@@ -771,7 +773,7 @@ ExecuteCommand(PARSED_COMMAND *Cmd)
Ret = ExecuteCommand(Sub->Next);
break;
case C_PIPE:
- ExecutePipeline(Cmd);
+ Ret = ExecutePipeline(Cmd);
break;
case C_IF:
Ret = ExecuteIf(Cmd);