From f6684c638d19e22fb6710794148634daccadc888 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Wed, 10 Apr 2013 16:30:42 +0400 Subject: [PATCH 1/3] Ticket #3001: fix read and update of subshell prompt. The bug was introduced in e35f044ccdd41922f925c99e6d50930ea8c7c47e. Signed-off-by: Andrew Borodin --- src/filemanager/layout.c | 21 +++++++++++++++------ src/subshell.c | 17 ++++++++++++++--- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c index 4a8d122cc..1d067dd66 100644 --- a/src/filemanager/layout.c +++ b/src/filemanager/layout.c @@ -8,7 +8,7 @@ Written by: Janne Kukonlehto, 1995 Miguel de Icaza, 1995 - Andrew Borodin , 2011, 2012 + Andrew Borodin , 2011, 2012, 2013 Slava Zanko , 2013 This file is part of the Midnight Commander. @@ -813,14 +813,16 @@ setup_cmdline (void) { int prompt_len; int y; - char *tmp_prompt = NULL; + char *tmp_prompt = (char *) mc_prompt; #ifdef ENABLE_SUBSHELL if (mc_global.tty.use_subshell) - tmp_prompt = strip_ctrl_codes (subshell_prompt->str); - if (tmp_prompt == NULL) + { + tmp_prompt = g_string_free (subshell_prompt, FALSE); + (void) strip_ctrl_codes (tmp_prompt); + } #endif - tmp_prompt = (char *) mc_prompt; + prompt_len = str_term_width1 (tmp_prompt); /* Check for prompts too big */ @@ -830,7 +832,14 @@ setup_cmdline (void) tmp_prompt[prompt_len] = '\0'; } - mc_prompt = tmp_prompt; +#ifdef ENABLE_SUBSHELL + if (mc_global.tty.use_subshell) + { + subshell_prompt = g_string_new (tmp_prompt); + g_free (tmp_prompt); + mc_prompt = subshell_prompt->str; + } +#endif y = LINES - 1 - mc_global.keybar_visible; diff --git a/src/subshell.c b/src/subshell.c index d2c3bc278..dfbc6bb55 100644 --- a/src/subshell.c +++ b/src/subshell.c @@ -985,6 +985,8 @@ read_subshell_prompt (void) int rc = 0; ssize_t bytes = 0; struct timeval timeleft = { 0, 0 }; + GString *p; + gboolean prompt_was_reset = FALSE; fd_set tmp; FD_ZERO (&tmp); @@ -994,6 +996,8 @@ read_subshell_prompt (void) if (subshell_prompt == NULL) subshell_prompt = g_string_sized_new (INITIAL_PROMPT_SIZE); + p = g_string_sized_new (INITIAL_PROMPT_SIZE); + while (subshell_alive && (rc = select (mc_global.tty.subshell_pty + 1, &tmp, NULL, NULL, &timeleft)) != 0) { @@ -1017,14 +1021,21 @@ read_subshell_prompt (void) bytes = read (mc_global.tty.subshell_pty, pty_buffer, sizeof (pty_buffer)); /* Extract the prompt from the shell output */ - g_string_set_size (subshell_prompt, 0); for (i = 0; i < bytes; i++) if (pty_buffer[i] == '\n' || pty_buffer[i] == '\r') - g_string_set_size (subshell_prompt, 0); + { + g_string_set_size (p, 0); + prompt_was_reset = TRUE; + } else if (pty_buffer[i] != '\0') - g_string_append_c (subshell_prompt, pty_buffer[i]); + g_string_append_c (p, pty_buffer[i]); } + if (p->len != 0 || prompt_was_reset) + g_string_assign (subshell_prompt, p->str); + + g_string_free (p, TRUE); + return (rc != 0 || bytes != 0); } From 5b1982a6bb8230972501d4017a6696c9ea9c497e Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Wed, 10 Apr 2013 16:41:29 +0400 Subject: [PATCH 2/3] (strip_ctrl_codes): type accuracy. Signed-off-by: Andrew Borodin --- lib/util.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/util.c b/lib/util.c index 84e2a63d2..a2ab25d5f 100644 --- a/lib/util.c +++ b/lib/util.c @@ -729,12 +729,11 @@ strip_ctrl_codes (char *s) { char *w; /* Current position where the stripped data is written */ char *r; /* Current position where the original data is read */ - char *n; - if (!s) - return 0; + if (s == NULL) + return NULL; - for (w = s, r = s; *r;) + for (w = s, r = s; *r != '\0';) { if (*r == ESC_CHAR) { @@ -743,7 +742,8 @@ strip_ctrl_codes (char *s) if (*(++r) == '[' || *r == '(') { /* strchr() matches trailing binary 0 */ - while (*(++r) && strchr ("0123456789;?", *r)); + while (*(++r) != '\0' && strchr ("0123456789;?", *r) != NULL) + ; } else if (*r == ']') { @@ -755,7 +755,7 @@ strip_ctrl_codes (char *s) */ char *new_r = r; - for (; *new_r; ++new_r) + for (; *new_r != '\0'; ++new_r) { switch (*new_r) { @@ -772,27 +772,32 @@ strip_ctrl_codes (char *s) } } } - osc_out:; + osc_out: + ; } /* * Now we are at the last character of the sequence. * Skip it unless it's binary 0. */ - if (*r) + if (*r != '\0') r++; - continue; } - - n = str_get_next_char (r); - if (str_isprint (r)) + else { - memmove (w, r, n - r); - w += n - r; + char *n; + + n = str_get_next_char (r); + if (str_isprint (r)) + { + memmove (w, r, n - r); + w += n - r; + } + r = n; } - r = n; } - *w = 0; + + *w = '\0'; return s; } From 74ed317f35775cc4975c30f5808a01c8af52fa33 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Thu, 11 Apr 2013 10:34:40 +0400 Subject: [PATCH 3/3] Cleanup: remove unused 'prompt_pos' variable. (do_subshell_chdir): remove 'reset_prompt' argument because of removed 'prompt_pos'. Signed-off-by: Andrew Borodin --- src/filemanager/panel.c | 4 ++-- src/subshell.c | 14 +++----------- src/subshell.h | 2 +- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 8ee076e6a..18555b72c 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -2,7 +2,7 @@ Panel managing. Copyright (C) 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2009, 2011, 2013 + 2005, 2006, 2007, 2009, 2011, 2012, 2013 The Free Software Foundation, Inc. Written by: @@ -3017,7 +3017,7 @@ subshell_chdir (const vfs_path_t * vpath) { #ifdef ENABLE_SUBSHELL if (mc_global.tty.use_subshell && vfs_current_is_local ()) - do_subshell_chdir (vpath, FALSE, TRUE); + do_subshell_chdir (vpath, FALSE); #else /* ENABLE_SUBSHELL */ (void) vpath; #endif /* ENABLE_SUBSHELL */ diff --git a/src/subshell.c b/src/subshell.c index dfbc6bb55..db1bbec85 100644 --- a/src/subshell.c +++ b/src/subshell.c @@ -174,11 +174,7 @@ static struct termios shell_mode; /* are delivered to the shell pty */ static struct termios raw_mode; -/* This counter indicates how many characters of prompt we have read */ -/* FIXME: try to figure out why this had to become global */ -static int prompt_pos; - - +/* --------------------------------------------------------------------------------------------- */ /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ /** @@ -935,7 +931,7 @@ invoke_subshell (const char *command, int how, vfs_path_t ** new_dir_vpath) /* Make the subshell change to MC's working directory */ if (new_dir_vpath != NULL) - do_subshell_chdir (current_panel->cwd_vpath, TRUE, TRUE); + do_subshell_chdir (current_panel->cwd_vpath, TRUE); if (command == NULL) /* The user has done "C-o" from MC */ { @@ -971,8 +967,6 @@ invoke_subshell (const char *command, int how, vfs_path_t ** new_dir_vpath) while (!subshell_alive && quit == 0 && mc_global.tty.use_subshell) init_subshell (); - prompt_pos = 0; - return quit; } @@ -1157,7 +1151,7 @@ subshell_name_quote (const char *s) /** If it actually changed the directory it returns true */ void -do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt, gboolean reset_prompt) +do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt) { char *pcwd; @@ -1237,8 +1231,6 @@ do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt, gboolean re } } - if (reset_prompt) - prompt_pos = 0; update_subshell_prompt = FALSE; g_free (pcwd); diff --git a/src/subshell.h b/src/subshell.h index 82cc2fe35..e0fdfb13e 100644 --- a/src/subshell.h +++ b/src/subshell.h @@ -43,7 +43,7 @@ int invoke_subshell (const char *command, int how, vfs_path_t ** new_dir); gboolean read_subshell_prompt (void); void do_update_prompt (void); gboolean exit_subshell (void); -void do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt, gboolean reset_prompt); +void do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt); void subshell_get_console_attributes (void); void sigchld_handler (int sig);