2024-02-28
| ||
08:01 | • Ticket [f91ab723f3] exec+wish fails to handle windows batch file with arguments and spaces status still Open with 4 other changes artifact: 5b793fcc9a user: oehhar | |
00:41 | • Ticket [f91ab723f3]: 3 changes artifact: 787360d42f user: anonymous | |
2024-02-27
| ||
20:23 | Bug [f91ab723f3] : remove Windows 16 bit dead code check-in: ce2bd7a315 user: oehhar tags: core-8-6-branch | |
2024-02-26
| ||
14:09 | • Ticket [f91ab723f3] exec+wish fails to handle windows batch file with arguments and spaces status still Open with 4 other changes artifact: 7b8a65fc15 user: oehhar | |
13:56 | Bug [f91ab723]: MS-WIN: remove dead code as TclWinGetPlatformId() constantly returns "VER_PLATFORM_W... Closed-Leaf check-in: 69a34921d1 user: oehhar tags: bug-f91ab723-dead-code-removal | |
13:34 | bug [f91ab723f3]: possible solution to remove cmd.exe handling. Leaf check-in: bdca8a3971 user: oehhar tags: bug-f91ab723f3-no-cmd | |
13:29 | Bug: [f91ab723f3]: possible solution to add quoting "" for cmd.exe /c argument Leaf check-in: 0530fbcf2d user: oehhar tags: bug-f91ab723f3-quoting | |
11:53 | • Ticket [f91ab723f3] exec+wish fails to handle windows batch file with arguments and spaces status still Open with 3 other changes artifact: 80835f0825 user: ralfixx | |
2024-02-23
| ||
10:01 | • Ticket [f91ab723f3]: 4 changes artifact: c025afff3d user: oehhar | |
09:57 | • Ticket [f91ab723f3]: 4 changes artifact: 18b701e85d user: oehhar | |
07:34 | • Ticket [f91ab723f3]: 3 changes artifact: 0b3d335c7f user: anonymous | |
2024-02-22
| ||
21:36 | • New ticket [f91ab723f3]. artifact: 59bc7fa31a user: anonymous | |
Ticket UUID: | f91ab723f3dfbc0d2b720a70a1fa09eebfa1cde5 | |||
Title: | exec+wish fails to handle windows batch file with arguments and spaces | |||
Type: | Bug | Version: | 8.6.13 | |
Submitter: | anonymous | Created on: | 2024-02-22 21:36:06 | |
Subsystem: | 16. Commands A-H | Assigned To: | nobody | |
Priority: | 5 Medium | Severity: | Minor | |
Status: | Open | Last Modified: | 2024-02-28 08:01:33 | |
Resolution: | None | Closed By: | nobody | |
Closed on: | ||||
Description: |
Reproduce the error with the following code run in wish console on Windows. Note that this works fine in tclsh: #Test4: set batFile {C:\batTest\bat test\test.bat} set arg1 {arg with spaces} set arg2 8 set command [list $batFile $arg1 $arg2] exec {*}$command Output: 'C:\batTest\bat' is not recognized as an internal or external command, operable program or batch file. Where the bat file just outputs all arguments given: @echo off (for %%a in (%*) do ( echo %%a )) Proper output can be reproduced if the space if removed from the bat file path or the argument: (bin) 54 % #Test1: set batFile {C:\batTest\bat test\test.bat} set arg1 {argNoSpaces} set arg2 8 set command [list $batFile $arg1 $arg2] exec {*}$command Output: argNoSpaces 8 (bin) 64 % #Test3: set batFile {C:\batTest\test.bat} set arg1 {arg with spaces} set arg2 8 set command [list $batFile $arg1 $arg2] exec {*}$command Output: "arg with spaces" 8 I have tested this in an older version of tcl (8.5.9) and it works fine. | |||
User Comments: |
oehhar added on 2024-02-28 08:01:33:
Great. It is now removed in 8.6(.15) too. It would be great, if someone could test or comment the two bugfix branches. Take care, Harald anonymous added on 2024-02-28 00:41:10: Note that the code line, if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { is no longer in 9.0b1, which was where I was getting the problem with cmd.exe /c and the quoting. For 8.6.13, I couldn't tell exactly what command line was being generated, and so having just built 9.0b1 from source, I used that to instrument the code. I did see it take the path and build up the cmd.exe /c so that should be fixed regardless. oehhar added on 2024-02-26 14:09:08: Please find two possible branches: Adding quotesSee branch bug-f91ab723f3-quoting starting with commit [0530fbcf2d]. A verbatim " is added around the argument. This causes the following test failure: ==== winFCmd-3.10 TclpDeleteFile: path is readonly FAILED ==== Contents of test case: createfile tf1 testchmod 0 tf1 testfile rm tf1 file exists tf1 ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ---- errorInfo: EACCES while executing "testfile rm tf1" ("uplevel" body line 4) invoked from within "uplevel 1 $script" ---- errorCode: NONE ==== winFCmd-3.10 FAILED Removing cmd.exeSee branch bug-f91ab723f3-no-cmd starting with commit [bdca8a3971]. The special handling with "cmd.exe /c" of batch files is totally removed. Dead CodeWhile looking into this, I remarked, that the following stubs-function returns a constant value: int TclWinGetPlatformId(void) { return VER_PLATFORM_WIN32_NT; } Thus, the else branch in win/tclWinPipe.c line 1092 if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { .... } else { if (HasConsole()) { createFlags = 0; } else { createFlags = DETACHED_PROCESS; } if (applType == APPL_DOS) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "DOS application process not supported on this platform", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "DOS_APP", NULL); goto end; } }can never be reached. This part is removed with commit [69a34921d1] in branch bug-f91ab723-dead-code-removal. Unfortunately, I always get a lot of test failures I am not able to explain (see below). Test failuresI ran tests in all 3 branches plus core-8-6-branch. I always get the following test failures. This is quite annoying, as the current 8.6.14rc1 has no test failures. ==== fCmd-9.3 file rename: comprehensive: file to new name FAILED ==== Contents of test case: createfile tf1 createfile tf2 testchmod 0o444 tf2 file rename tf1 tf3 file rename tf2 tf4 list [lsort [glob tf*]] [file writable tf3] [file writable tf4] ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ---- errorInfo: error renaming "tf2" to "tf4": permission denied while executing "file rename tf2 tf4" ("uplevel" body line 6) invoked from within "uplevel 1 $script" ---- errorCode: POSIX EACCES {permission denied} ==== fCmd-9.3 FAILED ==== fCmd-9.5 file rename: comprehensive: file to self FAILED ==== Contents of test case: createfile tf1 tf1 createfile tf2 tf2 testchmod 0o444 tf2 file rename -force tf1 tf1 file rename -force tf2 tf2 list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2] ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ---- errorInfo: error renaming "tf2": permission denied while executing "file rename -force tf2 tf2" ("uplevel" body line 6) invoked from within "uplevel 1 $script" ---- errorCode: POSIX EACCES {permission denied} ==== fCmd-9.5 FAILED ==== fCmd-9.7 file rename: comprehensive: file to existing file FAILED ==== Contents of test case: createfile tf1 createfile tf2 createfile tfs1 createfile tfs2 createfile tfs3 createfile tfs4 createfile tfd1 createfile tfd2 createfile tfd3 createfile tfd4 testchmod 0o444 tfs3 testchmod 0o444 tfs4 testchmod 0o444 tfd2 testchmod 0o444 tfd4 set msg [list [catch {file rename tf1 tf2} msg] $msg] file rename -force tfs1 tfd1 file rename -force tfs2 tfd2 file rename -force tfs3 tfd3 file rename -force tfs4 tfd4 list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4] ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ---- errorInfo: error renaming "tfs2" to "tfd2": permission denied while executing "file rename -force tfs2 tfd2" ("uplevel" body line 18) invoked from within "uplevel 1 $script" ---- errorCode: POSIX EACCES {permission denied} ==== fCmd-9.7 FAILED ==== fCmd-9.10 file rename: comprehensive: file to new name and dir FAILED ==== Contents of test case: createfile tf1 createfile tf2 file mkdir td1 testchmod 0o444 tf2 file rename tf1 [file join td1 tf3] file rename tf2 [file join td1 tf4] list [catch {glob tf*}] [lsort [glob -directory td1 t*]] [file writable [file join td1 tf3]] [file writable [file join td1 tf4]] ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ---- errorInfo: error renaming "tf2" to "td1/tf4": permission denied while executing "file rename tf2 [file join td1 tf4]" ("uplevel" body line 7) invoked from within "uplevel 1 $script" ---- errorCode: POSIX EACCES {permission denied} ==== fCmd-9.10 FAILED ==== winFCmd-3.10 TclpDeleteFile: path is readonly FAILED ==== Contents of test case: createfile tf1 testchmod 0 tf1 testfile rm tf1 file exists tf1 ---- Test generated error; Return code was: 1 ---- Return code should have been one of: 0 2 ---- errorInfo: EACCES while executing "testfile rm tf1" ("uplevel" body line 4) invoked from within "uplevel 1 $script" ---- errorCode: NONE ==== winFCmd-3.10 FAILED QuestionsMay I ask for an opinion what is wise? Those are the actions of a person with no experience here. May someone double-check the removal of the dead code? Thank you all and take care, Harald ralfixx added on 2024-02-26 11:53:12: This describes the quoting required in the "Remarks" section: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cmd oehhar added on 2024-02-23 10:01:52: I have not traced it. But it may happen, that the name of the batch file is replaced by the 8 character short name in ApplicationType(). So much work to do, renovate this very old code may be a challenge... Take care, Harald oehhar added on 2024-02-23 09:57:40: The upper code is in file win\tclWinPipe.c line 1126. The comment above the code } else if (applType == APPL_DOS) { /* * Under NT, 16-bit DOS applications will not run unless they can * be attached to a console. If we are running without a console, * run the 16-bit program as an normal process inside of a hidden * console application, and then run that hidden console as a * detached process. */only speaks about 16 bit DOS applications. So, we have two possible solutions:
We probably need tests in tk for this, so it is a double-project bug. Any comment appreciated, Harald anonymous added on 2024-02-23 07:34:22: When it's a batch job, i.e. something .bat, wish generates: cmd.exe /c "pa th\to.bat" "pa th/to.txt" 8 and that fails. If you enter that into a windows cmd window, it also fails *because* it needs to have another set of quotes around the whole string following the /c. Changing that in a cmd window to: cmd.exe /c ""pa th\to.bat" "pa th/to.txt" 8" and it works. When the path to the batch file has no spaces, it does not quote that, *and* will fail if you do add quotes anyway. Now that's really weird, but in fact I saw something about that in the documentation. However, adding quotes around the entire string will also make that case work. Now, if you use tclsh and exec, it ends up being just this: "pa th\to.bat" "pa th/to.txt" 8 and that works from tclsh and also in a cmd window. It's because the call to HasConsole() returns true in tclsh so that the command line is not prefixed with cmd.exe /c Here's the key code: if (HasConsole()) { createFlags = 0; } else if (applType == APPL_DOS) { /* * Under NT, 16-bit DOS applications will not run unless they can * be attached to a console. If we are running without a console, * run the 16-bit program as an normal process inside of a hidden * console application, and then run that hidden console as a * detached process. */ startInfo.wShowWindow = SW_HIDE; startInfo.dwFlags |= STARTF_USESHOWWINDOW; createFlags = CREATE_NEW_CONSOLE; TclDStringAppendLiteral(&cmdLine, "cmd.exe /c"); } else { createFlags = DETACHED_PROCESS; } |