From: Joe Souza jsouza@yahoo.com
--- programs/cmd/builtins.c | 17 +++--------- programs/cmd/directory.c | 4 +-- programs/cmd/wcmd.h | 5 ++-- programs/cmd/wcmdmain.c | 58 ++++++++++++++++++++++++++++++++++------ 4 files changed, 58 insertions(+), 26 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 5e084f9db92..b78ae9d293b 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1954,21 +1954,10 @@ RETURN_CODE WCMD_move(void) RETURN_CODE WCMD_pause(void) { RETURN_CODE return_code = NO_ERROR; - DWORD oldmode; - BOOL have_console; - DWORD count; - WCHAR key; - HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); - - have_console = GetConsoleMode(hIn, &oldmode); - if (have_console) - SetConsoleMode(hIn, 0); - WCMD_output_asis(anykey); - if (!WCMD_ReadFile(hIn, &key, 1, &count) || !count) - return_code = ERROR_INVALID_FUNCTION; - if (have_console) - SetConsoleMode(hIn, oldmode); + return_code = WCMD_wait_for_input(GetStdHandle(STD_INPUT_HANDLE)); + WCMD_output_asis(L"\r\n"); + return return_code; }
diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c index b7c036efd0d..a1efe0f20c9 100644 --- a/programs/cmd/directory.c +++ b/programs/cmd/directory.c @@ -305,7 +305,7 @@ static RETURN_CODE WCMD_list_directory (DIRECTORY_STACK *inputparms, int level,
/* Output the results */ if (!bare) { - if (level != 0 && (entry_count > 0)) WCMD_output_asis(L"\r\n"); + if (level != 0 && (entry_count > 0)) return_code = WCMD_output_asis(L"\r\n"); if (!recurse || ((entry_count > 0) && done_header==FALSE)) { WCMD_output (L"Directory of %1\n\n", real_path); done_header = TRUE; @@ -427,7 +427,7 @@ static RETURN_CODE WCMD_list_directory (DIRECTORY_STACK *inputparms, int level, } } } - if (addNewLine) WCMD_output_asis(L"\r\n"); + if (addNewLine) return_code = WCMD_output_asis(L"\r\n"); cur_width = 0;
/* Allow command to be aborted if user presses Ctrl-C. diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 225ebd44310..d4adc7fd7c8 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -174,8 +174,8 @@ RETURN_CODE WCMD_move (void); WCHAR* WINAPIV WCMD_format_string (const WCHAR *format, ...); void WINAPIV WCMD_output (const WCHAR *format, ...); void WINAPIV WCMD_output_stderr (const WCHAR *format, ...); -void WCMD_output_asis (const WCHAR *message); -void WCMD_output_asis_stderr (const WCHAR *message); +RETURN_CODE WCMD_output_asis (const WCHAR *message); +RETURN_CODE WCMD_output_asis_stderr (const WCHAR *message); RETURN_CODE WCMD_pause(void); RETURN_CODE WCMD_popd(void); void WCMD_print_error (void); @@ -210,6 +210,7 @@ void WCMD_HandleTildeModifiers(WCHAR **start, BOOL atExecute); WCHAR *WCMD_strip_quotes(WCHAR *cmd); WCHAR *WCMD_LoadMessage(UINT id); WCHAR *WCMD_strsubstW(WCHAR *start, const WCHAR* next, const WCHAR* insert, int len); +RETURN_CODE WCMD_wait_for_input(HANDLE hIn); BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars, LPDWORD charsRead);
enum read_parse_line {RPL_SUCCESS, RPL_EOF, RPL_SYNTAXERROR}; diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 77f1112be23..378a6448941 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -213,6 +213,44 @@ void WCMD_leave_paged_mode(void) pagedMessage = NULL; }
+/*************************************************************************** + * WCMD_wait_for_input + * + * Wait for input from a console/file. + * Used by commands like PAUSE and DIR /P that need to wait for user + * input before continuing. + */ +RETURN_CODE WCMD_wait_for_input(HANDLE hIn) +{ + RETURN_CODE return_code = NO_ERROR; + DWORD oldmode; + BOOL have_console; + DWORD count; + WCHAR key; + + have_console = GetConsoleMode(hIn, &oldmode); + if (have_console) { + SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT); + } + + /* Note that if ENABLE_PROCESSED_INPUT is specified in the call to + * SetConsoleMode above, then this function does not return when + * Ctrl-C is pressed. If ENABLE_PROCESSED_INPUT is not specified, + * then WCMD_ReadFile fails if Ctrl-C is pressed, and GLE is + * ERROR_NO_MORE_FILES. + */ + if (!WCMD_ReadFile(hIn, &key, 1, &count) || !count) { + if (GetLastError() == ERROR_NO_MORE_FILES) + return_code = STATUS_CONTROL_C_EXIT; + else + return_code = ERROR_INVALID_FUNCTION; + } + if (have_console) + SetConsoleMode(hIn, oldmode); + + return return_code; +} + /*************************************************************************** * WCMD_ReadFile * @@ -243,10 +281,9 @@ BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars, LPDWO * * Send output to specified handle without formatting e.g. when message contains '%' */ -static void WCMD_output_asis_handle (DWORD std_handle, const WCHAR *message) { - DWORD count; +static RETURN_CODE WCMD_output_asis_handle (DWORD std_handle, const WCHAR *message) { + RETURN_CODE return_code = NO_ERROR; const WCHAR* ptr; - WCHAR string[1024]; HANDLE handle = GetStdHandle(std_handle);
if (paged_mode) { @@ -262,12 +299,17 @@ static void WCMD_output_asis_handle (DWORD std_handle, const WCHAR *message) { if (++line_count >= max_height - 1) { line_count = 0; WCMD_output_asis_len(pagedMessage, lstrlenW(pagedMessage), handle); - WCMD_ReadFile(GetStdHandle(STD_INPUT_HANDLE), string, ARRAY_SIZE(string), &count); + return_code = WCMD_wait_for_input(GetStdHandle(STD_INPUT_HANDLE)); + WCMD_output_asis(L"\r\n"); + if (return_code) + break; } } while (((message = ptr) != NULL) && (*ptr)); } else { WCMD_output_asis_len(message, lstrlenW(message), handle); } + + return return_code; }
/******************************************************************* @@ -276,8 +318,8 @@ static void WCMD_output_asis_handle (DWORD std_handle, const WCHAR *message) { * Send output to current standard output device, without formatting * e.g. when message contains '%' */ -void WCMD_output_asis (const WCHAR *message) { - WCMD_output_asis_handle(STD_OUTPUT_HANDLE, message); +RETURN_CODE WCMD_output_asis (const WCHAR *message) { + return WCMD_output_asis_handle(STD_OUTPUT_HANDLE, message); }
/******************************************************************* @@ -286,8 +328,8 @@ void WCMD_output_asis (const WCHAR *message) { * Send output to current standard error device, without formatting * e.g. when message contains '%' */ -void WCMD_output_asis_stderr (const WCHAR *message) { - WCMD_output_asis_handle(STD_ERROR_HANDLE, message); +RETURN_CODE WCMD_output_asis_stderr (const WCHAR *message) { + return WCMD_output_asis_handle(STD_ERROR_HANDLE, message); }
/****************************************************************************