Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- programs/cmd/tests/batch.c | 58 +++++++++++++++-------- programs/cmd/tests/interactive_builtins.cmd | 1 programs/cmd/tests/interactive_builtins.cmd.exp | 1 programs/cmd/tests/rsrc.rc | 10 ++++ programs/cmd/wcmdmain.c | 9 +++- 5 files changed, 58 insertions(+), 21 deletions(-) create mode 100644 programs/cmd/tests/interactive_builtins.cmd create mode 100644 programs/cmd/tests/interactive_builtins.cmd.exp
diff --git a/programs/cmd/tests/batch.c b/programs/cmd/tests/batch.c index 0e8fbf89d6d..0d6832df30f 100644 --- a/programs/cmd/tests/batch.c +++ b/programs/cmd/tests/batch.c @@ -74,32 +74,39 @@ static const char* convert_input_data(const char *data, DWORD size, DWORD *new_s return new_data; }
-static BOOL run_cmd(const char *cmd_data, DWORD cmd_size) +static BOOL run_cmd(const char *cmd_data, DWORD cmd_size, BOOL interactive) { SECURITY_ATTRIBUTES sa = {sizeof(sa), 0, TRUE}; char command[] = "test.cmd"; + char interactive_command[] = "cmd /k"; /* so that we don't get version info before interactive mode */ STARTUPINFOA si = {sizeof(si)}; PROCESS_INFORMATION pi; - HANDLE file,fileerr; + HANDLE filein,fileout,fileerr; DWORD size; BOOL bres;
- file = CreateFileA("test.cmd", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n"); - if(file == INVALID_HANDLE_VALUE) + filein = CreateFileA("test.cmd", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, + interactive ? &sa : NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(filein != INVALID_HANDLE_VALUE, "CreateFile failed\n"); + if(filein == INVALID_HANDLE_VALUE) return FALSE;
- bres = WriteFile(file, cmd_data, cmd_size, &size, NULL); - CloseHandle(file); + bres = WriteFile(filein, cmd_data, cmd_size, &size, NULL); ok(bres, "Could not write to file: %u\n", GetLastError()); if(!bres) return FALSE; + if (interactive) + { + SetEndOfFile(filein); + SetFilePointer(filein, 0, NULL, FILE_BEGIN); + } + else + CloseHandle(filein);
- file = CreateFileA("test.out", GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, &sa, CREATE_ALWAYS, + fileout = CreateFileA("test.out", GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n"); - if(file == INVALID_HANDLE_VALUE) + ok(fileout != INVALID_HANDLE_VALUE, "CreateFile failed\n"); + if(fileout == INVALID_HANDLE_VALUE) return FALSE;
fileerr = CreateFileA("test.err", GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, &sa, CREATE_ALWAYS, @@ -109,9 +116,10 @@ static BOOL run_cmd(const char *cmd_data, DWORD cmd_size) return FALSE;
si.dwFlags = STARTF_USESTDHANDLES; - si.hStdOutput = file; + si.hStdInput = interactive ? filein : INVALID_HANDLE_VALUE; + si.hStdOutput = fileout; si.hStdError = fileerr; - bres = CreateProcessA(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); + bres = CreateProcessA(NULL, interactive ? interactive_command : command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); ok(bres, "CreateProcess failed: %u\n", GetLastError()); if(!bres) { DeleteFileA("test.out"); @@ -121,7 +129,9 @@ static BOOL run_cmd(const char *cmd_data, DWORD cmd_size) WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); - CloseHandle(file); + if (interactive) + CloseHandle(filein); + CloseHandle(fileout); CloseHandle(fileerr); DeleteFileA("test.cmd"); return TRUE; @@ -350,7 +360,7 @@ static void test_output(const char *out_data, DWORD out_size, const char *exp_da out_data + out_size - out_ptr, out_ptr); }
-static void run_test(const char *cmd_data, DWORD cmd_size, const char *exp_data, DWORD exp_size) +static void run_test(const char *cmd_data, DWORD cmd_size, const char *exp_data, DWORD exp_size, BOOL interactive) { const char *out_data, *actual_cmd_data; DWORD out_size, actual_cmd_size; @@ -359,7 +369,7 @@ static void run_test(const char *cmd_data, DWORD cmd_size, const char *exp_data, if(!actual_cmd_size || !actual_cmd_data) goto cleanup;
- if(!run_cmd(actual_cmd_data, actual_cmd_size)) + if(!run_cmd(actual_cmd_data, actual_cmd_size, interactive)) goto cleanup;
out_size = map_file("test.out", &out_data); @@ -394,7 +404,7 @@ static void run_from_file(const char *file_name) return; }
- run_test(test_data, test_size, out_data, out_size); + run_test(test_data, test_size, out_data, out_size, FALSE);
UnmapViewOfFile(test_data); UnmapViewOfFile(out_data); @@ -433,11 +443,11 @@ static BOOL WINAPI test_enum_proc(HMODULE module, LPCSTR type, LPSTR name, LONG_ return TRUE;
sprintf(res_name, "%s.exp", name); - out_size = load_resource(res_name, "TESTOUT", &out_data); + out_size = load_resource(res_name, param ? "INTERACTIVEOUT" : "TESTOUT", &out_data); if(!out_size) return TRUE;
- run_test(cmd_data, cmd_size, out_data, out_size); + run_test(cmd_data, cmd_size, out_data, out_size, param); return TRUE; }
@@ -483,7 +493,15 @@ START_TEST(batch)
argc = winetest_get_mainargs(&argv); if(argc > 2) - run_from_file(argv[2]); + { + if (!strcmp(argv[2], "--interactive")) + EnumResourceNamesA(NULL, "INTERACTIVECMD", test_enum_proc, 1); + else + run_from_file(argv[2]); + } else + { EnumResourceNamesA(NULL, "TESTCMD", test_enum_proc, 0); + EnumResourceNamesA(NULL, "INTERACTIVECMD", test_enum_proc, 1); + } } diff --git a/programs/cmd/tests/interactive_builtins.cmd b/programs/cmd/tests/interactive_builtins.cmd new file mode 100644 index 00000000000..546bad4eda5 --- /dev/null +++ b/programs/cmd/tests/interactive_builtins.cmd @@ -0,0 +1 @@ +@exit 0 diff --git a/programs/cmd/tests/interactive_builtins.cmd.exp b/programs/cmd/tests/interactive_builtins.cmd.exp new file mode 100644 index 00000000000..fe6f88e5414 --- /dev/null +++ b/programs/cmd/tests/interactive_builtins.cmd.exp @@ -0,0 +1 @@ +@pwd@>@exit 0 diff --git a/programs/cmd/tests/rsrc.rc b/programs/cmd/tests/rsrc.rc index affe04c2bdd..2d14bd25473 100644 --- a/programs/cmd/tests/rsrc.rc +++ b/programs/cmd/tests/rsrc.rc @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+/* the TEST(CMD|OUT) are run in batch mode, + * while the INTERACTIVE(CMD|OUT) are run in interactive mode. + */ + /* @makedep: test_builtins.cmd */ test_builtins.cmd TESTCMD "test_builtins.cmd"
@@ -27,3 +31,9 @@ test_cmdline.cmd TESTCMD "test_cmdline.cmd"
/* @makedep: test_cmdline.cmd.exp */ test_cmdline.cmd.exp TESTOUT "test_cmdline.cmd.exp" + +/* @makedep: interactive_builtins.cmd */ +interactive_builtins.cmd INTERACTIVECMD "interactive_builtins.cmd" + +/* @makedep: interactive_builtins.cmd.exp */ +interactive_builtins.cmd.exp INTERACTIVEOUT "interactive_builtins.cmd.exp" diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 65601348b05..ee863856ec9 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1897,6 +1897,13 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE WCMD_output_asis(L"\r\n"); }
+ /* echo input stream if naturally not echoed */ + if (!context && !optionalcmd && GetFileType(readFrom) != FILE_TYPE_CHAR) + { + WCMD_output_asis(curPos); + WCMD_output_asis(L"\r\n"); + /* FIXME: same quirk as above for trailing space? */ + } /* Skip repeated 'no echo' characters */ while (*curPos == '@') curPos++;
@@ -2762,7 +2769,7 @@ int __cdecl wmain (int argc, WCHAR *argvW[]) */
interactive = TRUE; - if (!opt_k) WCMD_version (); + if (!opt_k) WCMD_version (); else promptNewLine = FALSE; while (TRUE) {
/* Read until EOF (which for std input is never, but if redirect