From: Eric Pouech epouech@codeweavers.com
Mainly for commands not setting ERRORLEVEL in case of failure.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/batch.c | 21 +++++++++++++-------- programs/cmd/wcmd.h | 2 +- programs/cmd/wcmdmain.c | 10 ++++++++-- 3 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c index f350779a0db..17ef569dc3f 100644 --- a/programs/cmd/batch.c +++ b/programs/cmd/batch.c @@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(cmd); * a label to goto once opened. */
-void WCMD_batch (WCHAR *file, WCHAR *command, WCHAR *startLabel, HANDLE pgmHandle) +RETURN_CODE WCMD_batch(const WCHAR *file, WCHAR *command, const WCHAR *startLabel, HANDLE pgmHandle) { HANDLE h = INVALID_HANDLE_VALUE; BATCH_CONTEXT *prev_context; @@ -54,7 +54,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, WCHAR *startLabel, HANDLE pgmHandl if (h == INVALID_HANDLE_VALUE) { SetLastError (ERROR_FILE_NOT_FOUND); WCMD_print_error (); - return; + return ERROR_INVALID_FUNCTION; } } else { DuplicateHandle(GetCurrentProcess(), pgmHandle, @@ -106,9 +106,6 @@ void WCMD_batch (WCHAR *file, WCHAR *command, WCHAR *startLabel, HANDLE pgmHandl } CloseHandle (h);
- if (return_code != RETURN_CODE_ABORTED && return_code != RETURN_CODE_OLD_CHAINING) - errorlevel = return_code; - /* * If there are outstanding setlocal's to the current context, unwind them. */ @@ -124,6 +121,8 @@ void WCMD_batch (WCHAR *file, WCHAR *command, WCHAR *startLabel, HANDLE pgmHandl free(context->batchfileW); LocalFree(context); context = prev_context; + + return return_code; }
/******************************************************************* @@ -658,6 +657,7 @@ extern void WCMD_expand(const WCHAR *, WCHAR *); */ RETURN_CODE WCMD_call(WCHAR *command) { + RETURN_CODE return_code; WCHAR buffer[MAXSTRING]; WCMD_expand(command, buffer);
@@ -666,7 +666,9 @@ RETURN_CODE WCMD_call(WCHAR *command) { WCMD_run_program(buffer, TRUE); /* If the thing we try to run does not exist, call returns 1 */ - if (errorlevel) errorlevel = ERROR_INVALID_FUNCTION; + if (errorlevel == RETURN_CODE_CANT_LAUNCH) + errorlevel = ERROR_INVALID_FUNCTION; + return_code = errorlevel; } else if (context) { @@ -685,11 +687,14 @@ RETURN_CODE WCMD_call(WCHAR *command) li.u.LowPart = SetFilePointer(context->h, li.u.LowPart, &li.u.HighPart, FILE_CURRENT); WCMD_batch(context->batchfileW, buffer, gotoLabel, context->h); + return_code = errorlevel; SetFilePointer(context->h, li.u.LowPart, &li.u.HighPart, FILE_BEGIN);
/* Restore the for loop context */ WCMD_restore_for_loop_context(); - } else + } else { WCMD_output_asis_stderr(WCMD_LoadMessage(WCMD_CALLINSCRIPT)); - return errorlevel ? ERROR_INVALID_FUNCTION : NO_ERROR; + return_code = ERROR_INVALID_FUNCTION; + } + return return_code; } diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index c778e6bae5b..f79645495b3 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -160,7 +160,7 @@ typedef int RETURN_CODE; #define RETURN_CODE_OLD_CHAINING (-999998)
void WCMD_assoc (const WCHAR *, BOOL); -void WCMD_batch(WCHAR *, WCHAR *, WCHAR *, HANDLE); +RETURN_CODE WCMD_batch(const WCHAR *, WCHAR *, const WCHAR *, HANDLE); RETURN_CODE WCMD_call(WCHAR *command); void WCMD_change_tty (void); void WCMD_choice (const WCHAR *); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 7c19011f664..0f4c3ae8e3f 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1592,14 +1592,18 @@ void WCMD_run_program (WCHAR *command, BOOL called)
/* Special case BAT and CMD */ if (ext && (!wcsicmp(ext, L".bat") || !wcsicmp(ext, L".cmd"))) { + RETURN_CODE return_code; BOOL oldinteractive = interactive; + interactive = FALSE; - WCMD_batch(thisDir, command, NULL, INVALID_HANDLE_VALUE); + return_code = WCMD_batch(thisDir, command, NULL, INVALID_HANDLE_VALUE); interactive = oldinteractive; if (context && !called) { TRACE("Batch completed, but was not 'called' so skipping outer batch too\n"); context->skip_rest = TRUE; } + if (return_code != RETURN_CODE_ABORTED && return_code != RETURN_CODE_OLD_CHAINING) + errorlevel = return_code; return; } else { DWORD exit_code; @@ -3713,8 +3717,10 @@ RETURN_CODE node_execute(CMD_NODE *node) case CMD_ONFAILURE: return_code = node_execute(node->left); return_code = temp_fixup_return_code(node->left, return_code, ERROR_INVALID_FUNCTION); - if (return_code != NO_ERROR) + if (return_code != NO_ERROR && return_code != RETURN_CODE_ABORTED) { + /* that's needed for commands (POPD, RMDIR) that don't set errorlevel in case of failure. */ + errorlevel = return_code; return_code = node_execute(node->right); temp_fixup_return_code(node->right, return_code, 0 /* not used */); }