[PATCH v3 0/1] MR7252: cmd: add support for right-to-left handle redirection (2<&1)
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57795 Closes #57795 -- v3: cmd: add support for right-to-left handle redirection (2<&1) https://gitlab.winehq.org/wine/wine/-/merge_requests/7252
From: Damjan Jovanovic <damjan.jov(a)gmail.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57795 --- programs/cmd/tests/test_builtins.cmd | 5 +++++ programs/cmd/tests/test_builtins.cmd.exp | 3 +++ programs/cmd/wcmdmain.c | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 8552d51930a..a38456d95c5 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -176,6 +176,11 @@ del foo echo foo> foo echo foo7 7>> foo || (echo not supported & del foo) if exist foo (type foo) else echo not supported +echo --- right-to-left redirection +echo foo 1>foo-out 2>foo-err 1<&2 +findstr foo foo-out >nul 2>nul & if errorlevel 1 (echo not in foo-out) else echo in foo-out +findstr foo foo-err >nul 2>nul & if errorlevel 1 (echo not in foo-err) else echo in foo-err +erase /q foo-out foo-err echo --- redirect at beginning of line
foo (echo foo) type foo diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 292c24985e8..42cd415e147 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -204,6 +204,9 @@ food2 food21 foo7(a)space@@space@@or_broken(a)not supported(a)space@ foo(a)or_broken@not supported +--- right-to-left redirection +not in foo-out +in foo-err --- redirect at beginning of line foo foo1 diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index b19f8453438..3e248a6d36a 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -2627,8 +2627,20 @@ static void lexer_push_command(struct node_builder *builder,
if (*p == L'<') { - filename = WCMD_parameter(p + 1, 0, NULL, FALSE, FALSE); - tkn_pmt.redirection = redirection_create_file(REDIR_READ_FROM, 0, filename); + unsigned fd = 0; + + if (p > redirs && p[-1] >= L'0' && p[-1] <= L'9') fd = p[-1] - L'0'; + p++; + if (*p == L'&' && (p[1] >= L'0' && p[1] <= L'9')) + { + tkn_pmt.redirection = redirection_create_clone(fd, p[1] - L'0'); + p++; + } + else + { + filename = WCMD_parameter(p + 1, 0, NULL, FALSE, FALSE); + tkn_pmt.redirection = redirection_create_file(REDIR_READ_FROM, 0, filename); + } } else { @@ -2984,7 +2996,7 @@ enum read_parse_line WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE ** /* If a redirect is immediately followed by '&' (ie. 2>&1) then do not process that ampersand as an AND operator */ - if (thisChar == '>' && *(curPos+1) == '&') { + if ((thisChar == '>' || thisChar == '<') && *(curPos+1) == '&') { curCopyTo[(*curLen)++] = *(curPos+1); curPos++; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7252
On Tue Feb 4 17:02:04 2025 +0000, eric pouech wrote:
we could perhaps test that the cloning of the handle actually took place your test just shows that the parsing succeeds but nothing is actually written to 2 something like would do `dir /Z > foo 2<&1` `findstr . foo > NUL & if errorlevel 1 (echo not redirected) else echo redirected` Thank you, I've updated the test to check whether redirection to stderr happens.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/7252#note_93580
thanks for the update, your new first test is way cleaner... (just trying to simplify at most the tests and avoid calling external findstr, you could do `type foo-out 2> NUL || echo good` `type foo-err 2> NUL || echo bad` should output `good` `foo` (does work on native, should work on wine but didn't test it though) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7252#note_93585
participants (3)
-
Damjan Jovanovic -
Damjan Jovanovic (@dj) -
eric pouech (@epo)