From: Eric Pouech epouech@codeweavers.com
Some builtin commands don't set errorlevel upon success when run from a .bat while (while it's set when run from a .cmd file).
ASSOC, FTYPE, PATH, PROMPT, SET
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57139
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 38 +++++++++++++----------- programs/cmd/tests/test_builtins.bat.exp | 22 +++++++------- programs/cmd/wcmd.h | 12 +++++++- 3 files changed, 42 insertions(+), 30 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index ac4ed0ab049..7a7562d60d5 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -3279,7 +3279,8 @@ RETURN_CODE WCMD_setshow_env(WCHAR *s) } else if (!status) WCMD_print_error(); } } - return errorlevel = return_code; + return WCMD_is_in_context(L".bat") && return_code == NO_ERROR ? + return_code : (errorlevel = return_code); }
/**************************************************************************** @@ -3308,7 +3309,7 @@ RETURN_CODE WCMD_setshow_path(const WCHAR *args) return errorlevel = ERROR_INVALID_FUNCTION; } } - return errorlevel = NO_ERROR; + return WCMD_is_in_context(L".bat") ? NO_ERROR : (errorlevel = NO_ERROR); }
/**************************************************************************** @@ -3333,7 +3334,7 @@ RETURN_CODE WCMD_setshow_prompt(void) } else SetEnvironmentVariableW(L"PROMPT", s); } - return errorlevel = NO_ERROR; + return WCMD_is_in_context(L".bat") ? NO_ERROR : (errorlevel = NO_ERROR); }
/**************************************************************************** @@ -3882,16 +3883,17 @@ RETURN_CODE WCMD_exit(void) */ RETURN_CODE WCMD_assoc(const WCHAR *args, BOOL assoc) { - HKEY key; - DWORD accessOptions = KEY_READ; - WCHAR *newValue; - LONG rc = ERROR_SUCCESS; - WCHAR keyValue[MAXSTRING]; - DWORD valueLen; - HKEY readKey; + RETURN_CODE return_code; + HKEY key; + DWORD accessOptions = KEY_READ; + WCHAR *newValue; + LONG rc = ERROR_SUCCESS; + WCHAR keyValue[MAXSTRING]; + DWORD valueLen; + HKEY readKey;
/* See if parameter includes '=' */ - errorlevel = NO_ERROR; + return_code = NO_ERROR; newValue = wcschr(args, '='); if (newValue) accessOptions |= KEY_WRITE;
@@ -3966,7 +3968,7 @@ RETURN_CODE WCMD_assoc(const WCHAR *args, BOOL assoc) WCMD_output_asis(keyValue); WCMD_output_asis(L"\r\n"); RegCloseKey(readKey); - errorlevel = NO_ERROR; + return_code = NO_ERROR; } else { WCHAR msgbuffer[MAXSTRING];
@@ -3977,7 +3979,7 @@ RETURN_CODE WCMD_assoc(const WCHAR *args, BOOL assoc) LoadStringW(hinst, WCMD_NOFTYPE, msgbuffer, ARRAY_SIZE(msgbuffer)); } WCMD_output_stderr(msgbuffer, keyValue); - errorlevel = assoc ? ERROR_INVALID_FUNCTION : ERROR_FILE_NOT_FOUND; + return_code = assoc ? ERROR_INVALID_FUNCTION : ERROR_FILE_NOT_FOUND; }
/* Not a query - it's a set or clear of a value */ @@ -4010,7 +4012,7 @@ RETURN_CODE WCMD_assoc(const WCHAR *args, BOOL assoc)
} else if (rc != ERROR_FILE_NOT_FOUND) { WCMD_print_error(); - errorlevel = ERROR_FILE_NOT_FOUND; + return_code = ERROR_FILE_NOT_FOUND;
} else { WCHAR msgbuffer[MAXSTRING]; @@ -4022,7 +4024,7 @@ RETURN_CODE WCMD_assoc(const WCHAR *args, BOOL assoc) LoadStringW(hinst, WCMD_NOFTYPE, msgbuffer, ARRAY_SIZE(msgbuffer)); } WCMD_output_stderr(msgbuffer, args); - errorlevel = ERROR_FILE_NOT_FOUND; + return_code = ERROR_FILE_NOT_FOUND; }
/* It really is a set value = contents */ @@ -4038,7 +4040,7 @@ RETURN_CODE WCMD_assoc(const WCHAR *args, BOOL assoc)
if (rc != ERROR_SUCCESS) { WCMD_print_error(); - errorlevel = ERROR_FILE_NOT_FOUND; + return_code = ERROR_FILE_NOT_FOUND; } else { WCMD_output_asis(args); WCMD_output_asis(L"="); @@ -4051,8 +4053,8 @@ RETURN_CODE WCMD_assoc(const WCHAR *args, BOOL assoc)
/* Clean up */ RegCloseKey(key); - - return errorlevel; + return WCMD_is_in_context(L".bat") && return_code == NO_ERROR ? + return_code : (errorlevel = return_code); }
/**************************************************************************** diff --git a/programs/cmd/tests/test_builtins.bat.exp b/programs/cmd/tests/test_builtins.bat.exp index 12dd22effed..a2cbe0cecd7 100644 --- a/programs/cmd/tests/test_builtins.bat.exp +++ b/programs/cmd/tests/test_builtins.bat.exp @@ -166,26 +166,26 @@ FAILURE 1 --- success/failure for LABEL command FAILURE 1 --- success/failure for PATH command -@todo_wine@SUCCESS 666 -@todo_wine@SUCCESS 666 +SUCCESS 666 +SUCCESS 666 PATH=@:\I\dont\Exist@space@ -@todo_wine@SUCCESS 666 +SUCCESS 666 PATH=(null) -@todo_wine@SUCCESS 666 +SUCCESS 666 --- success/failure for SET command -@todo_wine@SUCCESS 666 -@todo_wine@SUCCESS 666 +SUCCESS 666 +SUCCESS 666 FAILURE 1 -@todo_wine@SUCCESS 666 -@todo_wine@SUCCESS 666 +SUCCESS 666 +SUCCESS 666 FAILURE 1 FAILURE 1 --- success/failure for ASSOC command -@todo_wine@SUCCESS 666 +SUCCESS 666 FAILURE 1 FAILURE 1 --- success/failure for FTYPE command -@todo_wine@SUCCESS 666 +SUCCESS 666 FAILURE 2 FAILURE 2 --- success/failure for SHIFT command @@ -197,7 +197,7 @@ FAILURE 1 FAILURE 1 SUCCESS 0 --- success/failure for PROMPT command -@todo_wine@SUCCESS 666 +SUCCESS 666 --- success/failure for CLS command @todo_wine@@formfeed@SUCCESS 666 @todo_wine@@formfeed@SUCCESS 666 diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 806b01d3393..ecb729efa00 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -340,7 +340,17 @@ extern BATCH_CONTEXT *context; extern FOR_CONTEXT *forloopcontext; extern BOOL delayedsubst;
-#endif /* !RC_INVOKED */ +static inline BOOL WCMD_is_in_context(const WCHAR *ext) +{ + size_t c_len, e_len; + if (!context) return FALSE; + if (!ext) return TRUE; + c_len = wcslen(context->batchfileW); + e_len = wcslen(ext); + return (c_len > e_len) && !wcsicmp(&context->batchfileW[c_len - e_len], ext); +} + + #endif /* !RC_INVOKED */
/* * Serial nos of builtin commands. These constants must be in step with