[PATCH v6 0/3] MR9112: XCOPY and COPY should not attempt to copy a file to itself.
Current code attempts to copy a file to itself. File is not actually copied; instead, a file sharing error is received. This result is ugly and differs from native. Behavior now appears to be the same as native with changes in this MR . -- v6: cmd: Don't attempt to copy a file to itself. https://gitlab.winehq.org/wine/wine/-/merge_requests/9112
From: Joe Souza <jsouza(a)yahoo.com> --- programs/xcopy/xcopy.c | 62 ++++++++++++++++++++++++++++++++++------- programs/xcopy/xcopy.h | 1 + programs/xcopy/xcopy.rc | 1 + 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/programs/xcopy/xcopy.c b/programs/xcopy/xcopy.c index ee30e07b184..3bb00d917e5 100644 --- a/programs/xcopy/xcopy.c +++ b/programs/xcopy/xcopy.c @@ -325,6 +325,37 @@ static BOOL XCOPY_ProcessExcludeList(WCHAR* parms) { return FALSE; } +/* ========================================================================= + * XCOPY_IsSameFile + * + * Checks if the two paths reference to the same file. + * Copied from WCMD builtins.c, and tab-adjusted. + * ========================================================================= */ +static BOOL XCOPY_IsSameFile(const WCHAR *name1, const WCHAR *name2) +{ + BOOL ret = FALSE; + HANDLE file1 = INVALID_HANDLE_VALUE, file2 = INVALID_HANDLE_VALUE; + BY_HANDLE_FILE_INFORMATION info1, info2; + + file1 = CreateFileW(name1, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (file1 == INVALID_HANDLE_VALUE || !GetFileInformationByHandle(file1, &info1)) + goto end; + + file2 = CreateFileW(name2, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (file2 == INVALID_HANDLE_VALUE || !GetFileInformationByHandle(file2, &info2)) + goto end; + + ret = info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber + && info1.nFileIndexHigh == info2.nFileIndexHigh + && info1.nFileIndexLow == info2.nFileIndexLow; +end: + if (file1 != INVALID_HANDLE_VALUE) + CloseHandle(file1); + if (file2 != INVALID_HANDLE_VALUE) + CloseHandle(file2); + return ret; +} + /* ========================================================================= XCOPY_DoCopy - Recursive function to copy files based on input parms of a stem and a spec @@ -345,7 +376,7 @@ static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec, WCHAR *inputpath, *outputpath; BOOL copiedFile = FALSE; DWORD destAttribs, srcAttribs; - BOOL skipFile; + BOOL skipFile, quitCopy = FALSE; int ret = 0; /* Allocate some working memory on heap to minimize footprint */ @@ -359,7 +390,7 @@ static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec, /* Search 1 - Look for matching files */ h = FindFirstFileW(inputpath, finddata); - while (h != INVALID_HANDLE_VALUE && findres) { + while (h != INVALID_HANDLE_VALUE && !quitCopy && findres) { skipFile = FALSE; @@ -465,6 +496,18 @@ static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec, } } + /* Don't copy a file over itself. */ + if (XCOPY_IsSameFile(copyFrom, copyTo)) { + skipFile = quitCopy = TRUE; + if (!(flags & OPT_QUIET)) { + if (flags & OPT_FULL) + XCOPY_wprintf(L"%1 -> %2\n", copyFrom, copyTo); + else + XCOPY_wprintf(L"%1\n", copyFrom); + } + XCOPY_wprintf(XCOPY_LoadMessage(STRING_NOCOPYTOSELF)); + } + /* Prompt each file if necessary */ if (!skipFile && (flags & OPT_SRCPROMPT)) { DWORD count; @@ -550,11 +593,10 @@ static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec, copyFrom, copyTo, error); XCOPY_FailMessage(error); - if (flags & OPT_IGNOREERRORS) { - skipFile = TRUE; - } else { + skipFile = TRUE; + if (!(flags & OPT_IGNOREERRORS)) { ret = RC_WRITEERROR; - goto cleanup; + quitCopy = TRUE; } } else { @@ -580,12 +622,14 @@ static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec, } /* Find next file */ - findres = FindNextFileW(h, finddata); + if (!quitCopy) { + findres = FindNextFileW(h, finddata); + } } FindClose(h); /* Search 2 - do subdirs */ - if (flags & OPT_RECURSIVE) { + if (!quitCopy && (flags & OPT_RECURSIVE)) { /* If /E is supplied, create the directory now */ if ((flags & OPT_EMPTYDIR) && @@ -628,8 +672,6 @@ static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec, FindClose(h); } -cleanup: - /* free up memory */ HeapFree(GetProcessHeap(), 0, finddata); HeapFree(GetProcessHeap(), 0, inputpath); diff --git a/programs/xcopy/xcopy.h b/programs/xcopy/xcopy.h index 1ed9e20c45b..70b0935ba2c 100644 --- a/programs/xcopy/xcopy.h +++ b/programs/xcopy/xcopy.h @@ -69,3 +69,4 @@ #define STRING_FILE_CHAR 115 #define STRING_DIR_CHAR 116 #define STRING_HELP 117 +#define STRING_NOCOPYTOSELF 118 diff --git a/programs/xcopy/xcopy.rc b/programs/xcopy/xcopy.rc index c61e4da88fd..b12eeb4b068 100644 --- a/programs/xcopy/xcopy.rc +++ b/programs/xcopy/xcopy.rc @@ -79,4 +79,5 @@ Where:\n\ \t\tIf no date is supplied, only copy if destination is older\n\ \t\tthan source.\n\n" + STRING_NOCOPYTOSELF, "File cannot be copied to itself.\n" } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9112
From: Joe Souza <jsouza(a)yahoo.com> --- programs/cmd/tests/test_builtins.bat | 4 ++++ programs/cmd/tests/test_builtins.bat.exp | 3 +++ programs/cmd/tests/test_builtins.cmd | 4 ++++ programs/cmd/tests/test_builtins.cmd.exp | 3 +++ 4 files changed, 14 insertions(+) diff --git a/programs/cmd/tests/test_builtins.bat b/programs/cmd/tests/test_builtins.bat index dc624111213..26f2803beab 100644 --- a/programs/cmd/tests/test_builtins.bat +++ b/programs/cmd/tests/test_builtins.bat @@ -114,6 +114,10 @@ call :setError 666 & (copy fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel! call :setError 666 & (copy fileA+fileD fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileD+fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) if exist fileD echo Unexpected fileD +call :setError 666 & (copy fileA fileA /Y >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (copy fileA+fileB fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +echo a > fileA +call :setError 666 & (copy fileA+fileB fileB >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) cd .. && rd /q /s foo echo --- success/failure for MOVE command diff --git a/programs/cmd/tests/test_builtins.bat.exp b/programs/cmd/tests/test_builtins.bat.exp index d3f23abde77..e5decac7539 100644 --- a/programs/cmd/tests/test_builtins.bat.exp +++ b/programs/cmd/tests/test_builtins.bat.exp @@ -77,6 +77,9 @@ SUCCESS 0 FAILURE 1 FAILURE 1 FAILURE 1 +FAILURE 1 +SUCCESS 0 +(a)todo_wine@SUCCESS 0 --- success/failure for MOVE command FAILURE 1 SUCCESS 0 diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 19dc3c788bb..d069823f7fd 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -639,6 +639,10 @@ call :setError 666 & (copy fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel! call :setError 666 & (copy fileA+fileD fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileD+fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) if exist fileD echo Unexpected fileD +call :setError 666 & (copy fileA fileA /Y >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (copy fileA+fileB fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +echo a > fileA +call :setError 666 & (copy fileA+fileB fileB >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) cd .. && rd /q /s foo echo --- success/failure for MOVE command diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 644ca910c8c..9a76b173949 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -541,6 +541,9 @@ SUCCESS 0 FAILURE 1 FAILURE 1 FAILURE 1 +FAILURE 1 +SUCCESS 0 +(a)todo_wine@SUCCESS 0 --- success/failure for MOVE command FAILURE 1 SUCCESS 0 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9112
From: Joe Souza <jsouza(a)yahoo.com> --- programs/cmd/builtins.c | 17 ++++++++++++++--- programs/cmd/cmd.rc | 1 + programs/cmd/tests/test_builtins.bat | 2 +- programs/cmd/tests/test_builtins.cmd | 2 +- programs/cmd/wcmd.h | 1 + 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index ef84bee64ac..7d560143be2 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1041,6 +1041,7 @@ RETURN_CODE WCMD_copy(WCHAR * args) WCHAR outname[MAX_PATH]; BOOL overwrite; BOOL appendtofirstfile = FALSE; + BOOL issamefile; /* Skip . and .., and directories */ if (!srcisdevice && fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -1060,13 +1061,23 @@ RETURN_CODE WCMD_copy(WCHAR * args) overwrite = TRUE; } + issamefile = WCMD_IsSameFile(srcpath, outname); + WINE_TRACE("Copying from : '%s'\n", wine_dbgstr_w(srcpath)); WINE_TRACE("Copying to : '%s'\n", wine_dbgstr_w(outname)); WINE_TRACE("Flags: srcbinary(%d), dstbinary(%d), over(%d), prompt(%d)\n", thiscopy->binarycopy, destination->binarycopy, overwrite, prompt); + if (!anyconcats && issamefile) { + WCMD_output_asis(srcpath); + WCMD_output_asis(L"\r\n"); + WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOCOPYTOSELF)); + return_code = ERROR_INVALID_FUNCTION; + break; + } + if (!writtenoneconcat) { - appendtofirstfile = anyconcats && WCMD_IsSameFile(srcpath, outname); + appendtofirstfile = anyconcats && issamefile; } /* Prompt before overwriting */ @@ -1098,7 +1109,7 @@ RETURN_CODE WCMD_copy(WCHAR * args) WCMD_output_asis(srcpath); WCMD_output_asis(L"\r\n"); } - if (anyconcats && WCMD_IsSameFile(srcpath, outname)) { + if (anyconcats && issamefile) { /* behavior is as Unix 'touch' (change last-written time only) */ HANDLE file = CreateFileW(srcpath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -1168,7 +1179,7 @@ RETURN_CODE WCMD_copy(WCHAR * args) } } - if (numcopied) { + if (numcopied || return_code) { WCMD_output(WCMD_LoadMessage(WCMD_NUMCOPIED), numcopied); } diff --git a/programs/cmd/cmd.rc b/programs/cmd/cmd.rc index 29d105fa7a2..322673aab30 100644 --- a/programs/cmd/cmd.rc +++ b/programs/cmd/cmd.rc @@ -407,4 +407,5 @@ Enter HELP <command> for further information on any of the above commands.\n" WCMD_ENDOFLINE, "End of line" WCMD_ENDOFFILE, "End of file" WCMD_NUMCOPIED, "%t%1!u! file(s) copied\n" + WCMD_NOCOPYTOSELF, "File cannot be copied to itself.\n" } diff --git a/programs/cmd/tests/test_builtins.bat b/programs/cmd/tests/test_builtins.bat index 26f2803beab..b4cc25d3898 100644 --- a/programs/cmd/tests/test_builtins.bat +++ b/programs/cmd/tests/test_builtins.bat @@ -114,7 +114,7 @@ call :setError 666 & (copy fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel! call :setError 666 & (copy fileA+fileD fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileD+fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) if exist fileD echo Unexpected fileD -call :setError 666 & (copy fileA fileA /Y >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (copy fileA fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileA+fileB fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) echo a > fileA call :setError 666 & (copy fileA+fileB fileB >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index d069823f7fd..1b5e702ffc4 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -639,7 +639,7 @@ call :setError 666 & (copy fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel! call :setError 666 & (copy fileA+fileD fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileD+fileA fileZ /-Y >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) if exist fileD echo Unexpected fileD -call :setError 666 & (copy fileA fileA /Y >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (copy fileA fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy fileA+fileB fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) echo a > fileA call :setError 666 & (copy fileA+fileB fileB >NUL <NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 6810598142c..ba18b942c5d 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -477,3 +477,4 @@ extern WCHAR version_string[]; #define WCMD_ENDOFLINE 1048 #define WCMD_ENDOFFILE 1049 #define WCMD_NUMCOPIED 1050 +#define WCMD_NOCOPYTOSELF 1051 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9112
Thought I had a fix (manual case seemed to be fixed) but the tests still failed so I backed out that change. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_118334
Long delays here because the COPY tests output do not match those of native Windows 10, even without my code changes here. My code changes here were meant to be minor and fairly quick. I had not intended to track down the reasons for the difference in COPY's return code values between native and Wine. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_118755
eric pouech (@epo) commented about programs/cmd/builtins.c:
} }
- if (numcopied) {
this change looks very dubious -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_118877
fixing cmd.exe can sometimes be tedious your intent is to fix COPY command when asked to have the same file as source and destination the goal should be to replace the broken parts with correct code, not (half) broken (eg. the CI is reports failures with this patch) I'd suggest you use these changes for the tests (derived from your work) to be used in both .cmd and .bat context ``` call :setError 666 & (copy /b fileA fileA /Y >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy /b fileA+fileB fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) type fileA echo a > fileA call :setError 666 & (copy /b fileA+fileB /Y fileB >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) type fileB ``` but basically, for multiple source files, if one of the source file is the dest file: - if it's not the first one, cmd.exe will ask for permission to overwrite it, but will do nothing - if it's the first one, it proceeeds by appending the next files - success is always returned - I believe some of your tests are failing because of the missing /Y option, and fails with the overwrite question some notes: - COPY /B will prevent appending a ctrl-z which will be a pain with the TYPE output - I didn't cover the behaviors without /Y (which is another dimension); but this should covered at some point in time if you wish you can concentrate first only on the single source file case and leave the multiple one for later on (tests can be added for the single & multiple cases, but the todo_wine should mark the missing bits) also XCOPY will need tests -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_118878
On Fri Oct 17 10:35:03 2025 +0000, eric pouech wrote:
fixing cmd.exe can sometimes be tedious your intent is to fix COPY command when asked to have the same file as source and destination the goal should be to replace the broken parts with correct code, not (half) broken (eg. the CI is reports failures with this patch) I'd suggest you use these changes for the tests (derived from your work) to be used in both .cmd and .bat context ``` call :setError 666 & (copy /b fileA fileA /Y >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (copy /b fileA+fileB fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) type fileA echo a > fileA call :setError 666 & (copy /b fileA+fileB /Y fileB >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) type fileB ``` but basically, for multiple source files, if one of the source file is the dest file: - if it's not the first one, cmd.exe will ask for permission to overwrite it, but will do nothing - if it's the first one, it proceeeds by appending the next files - success is always returned - I believe some of your tests are failing because of the missing /Y option, and fails with the overwrite question some notes: - COPY /B will prevent appending a ctrl-z which will be a pain with the TYPE output - I didn't cover the behaviors without /Y (which is another dimension); but this should covered at some point in time if you wish you can concentrate first only on the single source file case and leave the multiple one for later on (tests can be added for the single & multiple cases, but the todo_wine should mark the missing bits) also XCOPY will need tests Note that the tests are not failing, at least not for me. The problem is that the output of the tests (the success/failure for COPY tests) differ from those of native Windows 10. That's what I've been trying to track down, but I've spent a lot of time on this and am becoming discouraged.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_118966
On Fri Oct 17 20:48:09 2025 +0000, Joe Souza wrote:
Note that the tests are not failing, at least not for me. The problem is that the output of the tests (the success/failure for COPY tests) differ from those of native Windows 10. That's what I've been trying to track down, but I've spent a lot of time on this and am becoming discouraged. I also have some travel coming up so I may abandon this change, or at a minimum leave it for a later time.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_118967
On Fri Oct 17 20:48:44 2025 +0000, Joe Souza wrote:
I also have some travel coming up so I may abandon this change, or at a minimum leave it for a later time. To be 100% clear, the *existing* tests yield differing output on Windows 10 and Wine 10.16. These are the existing tests, without any of my changes here.
Output on Windows 10: ``` --- success/failure for COPY command FAILURE 0 SUCCESS 1 SUCCESS 0 FAILURE 0 FAILURE 1 ``` Output on Wine 10.16: ``` --- success/failure for COPY command FAILURE 0 SUCCESS 1 FAILURE 0 FAILURE 1 FAILURE 1 ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_118970
it's not clear to me how you run the windows test when you report failure? since it works locally for me, and also on the various tests env [1], there could be some discrepancy in settings? what could differ: - HKLM / HKCU registry entry for L"Software\\Microsoft\\Command Processor" which sets some bits (we likely need to run a couple of cmd.exe instances with /D which is not done yet) - some copy related env variables (eg COPYCMD) is set (we should propably always define a proper value for the tests though) - you somehow run the tests through an interactive cmd.exe prompt while the tests usually are not - you have leftovers in current directory (various files) from previous run, and testing from an empty directory could help [1] just reran testbot on upstream Wine for cmd.exe:batch tests: https://testbot.winehq.org/JobDetails.pl?Key=160395 which shows no error on windows VM -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_119356
I think I found *a* problem, not sure yet if this is related to the difference in the test output on Windows vs Wine, but it does appear to be a problem and coincides with my discovery that I mentioned above that ```< NUL``` (with space) works, while ```<NUL``` (no space) does not. In the log output excerpt here, look at that last line: ```REDIR {{0< (UL)}}```. Somehow, the leading 'N' has been parsed-out. ``` 0134:trace:cmd:WCMD_ReadAndParseLine About to parse line (call :setError 666 & (copy fileA fileZ /-Y >NUL <NUL &&echo SUCCESS 0||echo FAILURE 0)) 0134:trace:cmd:node_builder_parse 0/12) CMD {{L"call :setError 666 "}} 0134:trace:cmd:node_builder_parse 1/12) & 0134:trace:cmd:node_builder_parse 2/12) ( 0134:trace:cmd:node_builder_parse 3/12) REDIR {{1> (NUL)}} 0134:trace:cmd:node_builder_parse 4/12) REDIR {{0< (UL)}} ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_119357
On Wed Oct 22 17:16:48 2025 +0000, eric pouech wrote:
it's not clear to me how you run the windows test when you report failure? since it works locally for me, and also on the various tests env [1], there could be some discrepancy in settings? what could differ: - HKLM / HKCU registry entry for L"Software\\Microsoft\\Command Processor" which sets some bits (we likely need to run a couple of cmd.exe instances with /D which is not done yet) - some copy related env variables (eg COPYCMD) is set (we should propably always define a proper value for the tests though) - you somehow run the tests through an interactive cmd.exe prompt while the tests usually are not - you have leftovers in current directory (various files) from previous run, and testing from an empty directory could help [1] just reran testbot on upstream Wine for cmd.exe:batch tests: https://testbot.winehq.org/JobDetails.pl?Key=160395 which shows no error on windows VM Just saw your comment here, as I was posting my comment below. Seems we both posted at roughly the same time. I admit that it is possible that there is some difference in my setup/environment here. I should try cleaning my build tree and rebuilding, and perhaps deleting my Wine prefix, etc.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_119358
yeah there's a bug in lexer... that should fix it ``` diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 46b89544221..103eaa486c8 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -3102,7 +3102,7 @@ static void lexer_push_command(struct node_builder *builder, } else { - filename = WCMD_parameter(p + 1, 0, NULL, FALSE, FALSE); + filename = WCMD_parameter(p, 0, NULL, FALSE, FALSE); tkn_pmt.redirection = redirection_create_file(REDIR_READ_FROM, 0, filename); } } ``` but that would only explain the discrepancies if there happens to be a file named 'ul' in the test directory -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_119361
On Wed Oct 22 17:41:51 2025 +0000, eric pouech wrote:
yeah there's a bug in lexer... that should fix it ``` diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 46b89544221..103eaa486c8 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -3102,7 +3102,7 @@ static void lexer_push_command(struct node_builder *builder, } else { - filename = WCMD_parameter(p + 1, 0, NULL, FALSE, FALSE); + filename = WCMD_parameter(p, 0, NULL, FALSE, FALSE); tkn_pmt.redirection = redirection_create_file(REDIR_READ_FROM, 0, filename); } } ``` but that would only explain the discrepancies if there happens to be a file named 'ul' in the test directory Thanks for that. I will try that later today. I just started a clean build which will take a very long time to complete on my machine. Regarding that, I realize that the problem should not be related to my build at all, because I was seeing the problem on stock 10.16 on a completely different machine. I'll see what happens with the lexer change later today.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9112#note_119362
participants (3)
-
eric pouech (@epo) -
Joe Souza -
Joe Souza (@JoeS209)