mirror of
https://github.com/sheumann/hush.git
synced 2024-10-29 20:27:40 +00:00
cmdedit: more optimizations
This commit is contained in:
parent
47bdb3ac48
commit
5592fac308
246
shell/cmdedit.c
246
shell/cmdedit.c
@ -119,14 +119,6 @@ static struct termios initial_settings, new_settings;
|
|||||||
|
|
||||||
static
|
static
|
||||||
volatile unsigned cmdedit_termw = 80; /* actual terminal width */
|
volatile unsigned cmdedit_termw = 80; /* actual terminal width */
|
||||||
static
|
|
||||||
volatile int handlers_sets = 0; /* Set next bits: */
|
|
||||||
enum {
|
|
||||||
SET_ATEXIT = 1, /* when atexit() has been called
|
|
||||||
and get euid,uid,gid to fast compare */
|
|
||||||
SET_WCHG_HANDLERS = 2, /* winchg signal handler */
|
|
||||||
SET_RESET_TERM = 4, /* if the terminal needs to be reset upon exit */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int cmdedit_x; /* real x terminal position */
|
static int cmdedit_x; /* real x terminal position */
|
||||||
@ -148,10 +140,6 @@ static char *user_buf = "";
|
|||||||
static char *home_pwd_buf = "";
|
static char *home_pwd_buf = "";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR || ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
|
||||||
static int my_euid;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
||||||
static int my_uid;
|
static int my_uid;
|
||||||
static int my_gid;
|
static int my_gid;
|
||||||
@ -339,7 +327,6 @@ static void input_backspace(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Move forward one character */
|
/* Move forward one character */
|
||||||
static void input_forward(void)
|
static void input_forward(void)
|
||||||
{
|
{
|
||||||
@ -347,10 +334,21 @@ static void input_forward(void)
|
|||||||
cmdedit_set_out_char(command_ps[cursor + 1]);
|
cmdedit_set_out_char(command_ps[cursor + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
||||||
|
|
||||||
static char **matches;
|
static char **matches;
|
||||||
static int num_matches;
|
static unsigned num_matches;
|
||||||
|
|
||||||
|
static void free_tab_completion_data(void)
|
||||||
|
{
|
||||||
|
if (matches) {
|
||||||
|
while (num_matches)
|
||||||
|
free(matches[--num_matches]);
|
||||||
|
free(matches);
|
||||||
|
matches = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void add_match(char *matched)
|
static void add_match(char *matched)
|
||||||
{
|
{
|
||||||
@ -363,7 +361,6 @@ static void add_match(char *matched)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION
|
#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION
|
||||||
|
|
||||||
static void username_tab_completion(char *ud, char *with_shash_flg)
|
static void username_tab_completion(char *ud, char *with_shash_flg)
|
||||||
{
|
{
|
||||||
struct passwd *entry;
|
struct passwd *entry;
|
||||||
@ -504,7 +501,6 @@ static void exe_n_cwd_tab_completion(char *command, int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < npaths; i++) {
|
for (i = 0; i < npaths; i++) {
|
||||||
|
|
||||||
dir = opendir(paths[i]);
|
dir = opendir(paths[i]);
|
||||||
if (!dir) /* Don't print an error */
|
if (!dir) /* Don't print an error */
|
||||||
continue;
|
continue;
|
||||||
@ -559,7 +555,6 @@ static void exe_n_cwd_tab_completion(char *command, int type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define QUOT (UCHAR_MAX+1)
|
#define QUOT (UCHAR_MAX+1)
|
||||||
|
|
||||||
#define collapse_pos(is, in) { \
|
#define collapse_pos(is, in) { \
|
||||||
@ -580,8 +575,8 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
|||||||
if (int_buf[i] == 0) {
|
if (int_buf[i] == 0) {
|
||||||
pos_buf[i] = -1; /* indicator end line */
|
pos_buf[i] = -1; /* indicator end line */
|
||||||
break;
|
break;
|
||||||
} else
|
}
|
||||||
pos_buf[i] = i;
|
pos_buf[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mask \+symbol and convert '\t' to ' ' */
|
/* mask \+symbol and convert '\t' to ' ' */
|
||||||
@ -731,9 +726,9 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
display by column original ideas from ls applet,
|
* display by column (original idea from ls applet,
|
||||||
very optimize by my :)
|
* very optimized by me :)
|
||||||
*/
|
*/
|
||||||
static void showfiles(void)
|
static void showfiles(void)
|
||||||
{
|
{
|
||||||
int ncols, row;
|
int ncols, row;
|
||||||
@ -770,11 +765,6 @@ static void showfiles(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_compare(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
return strcmp(*(char**)a, *(char**)b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *add_quote_for_spec_chars(char *found)
|
static char *add_quote_for_spec_chars(char *found)
|
||||||
{
|
{
|
||||||
int l = 0;
|
int l = 0;
|
||||||
@ -789,18 +779,14 @@ static char *add_quote_for_spec_chars(char *found)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int match_compare(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
return strcmp(*(char**)a, *(char**)b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do TAB completion */
|
||||||
static void input_tab(int *lastWasTab)
|
static void input_tab(int *lastWasTab)
|
||||||
{
|
{
|
||||||
/* Do TAB completion */
|
|
||||||
if (lastWasTab == 0) { /* free all memory */
|
|
||||||
if (matches) {
|
|
||||||
while (num_matches > 0)
|
|
||||||
free(matches[--num_matches]);
|
|
||||||
free(matches);
|
|
||||||
matches = (char **) NULL;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!*lastWasTab) {
|
if (!*lastWasTab) {
|
||||||
char *tmp, *tmp1;
|
char *tmp, *tmp1;
|
||||||
int len_found;
|
int len_found;
|
||||||
@ -813,12 +799,12 @@ static void input_tab(int *lastWasTab)
|
|||||||
/* Make a local copy of the string -- up
|
/* Make a local copy of the string -- up
|
||||||
* to the position of the cursor */
|
* to the position of the cursor */
|
||||||
tmp = strncpy(matchBuf, command_ps, cursor);
|
tmp = strncpy(matchBuf, command_ps, cursor);
|
||||||
tmp[cursor] = 0;
|
tmp[cursor] = '\0';
|
||||||
|
|
||||||
find_type = find_match(matchBuf, &recalc_pos);
|
find_type = find_match(matchBuf, &recalc_pos);
|
||||||
|
|
||||||
/* Free up any memory already allocated */
|
/* Free up any memory already allocated */
|
||||||
input_tab(0);
|
free_tab_completion_data();
|
||||||
|
|
||||||
#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION
|
#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION
|
||||||
/* If the word starts with `~' and there is no slash in the word,
|
/* If the word starts with `~' and there is no slash in the word,
|
||||||
@ -829,24 +815,24 @@ static void input_tab(int *lastWasTab)
|
|||||||
if (!matches)
|
if (!matches)
|
||||||
#endif
|
#endif
|
||||||
/* Try to match any executable in our path and everything
|
/* Try to match any executable in our path and everything
|
||||||
* in the current working directory that matches. */
|
* in the current working directory */
|
||||||
exe_n_cwd_tab_completion(matchBuf, find_type);
|
exe_n_cwd_tab_completion(matchBuf, find_type);
|
||||||
/* Sort, then remove any duplicates found */
|
/* Sort, then remove any duplicates found */
|
||||||
if (matches) {
|
if (matches) {
|
||||||
int i, n = 0;
|
int i, n = 0;
|
||||||
qsort(matches, num_matches, sizeof(char*), match_compare);
|
qsort(matches, num_matches, sizeof(char*), match_compare);
|
||||||
for (i = 0; i < num_matches - 1; ++i) {
|
for (i = 0; i < num_matches - 1; ++i) {
|
||||||
if (matches[i] && matches[i+1]) {
|
if (matches[i] && matches[i+1]) { /* paranoia */
|
||||||
if (strcmp(matches[i], matches[i+1]) == 0) {
|
if (strcmp(matches[i], matches[i+1]) == 0) {
|
||||||
free(matches[i]);
|
free(matches[i]);
|
||||||
matches[i] = 0;
|
matches[i] = NULL; /* paranoia */
|
||||||
} else {
|
} else {
|
||||||
matches[n++] = matches[i];
|
matches[n++] = matches[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
matches[n++] = matches[num_matches-1];
|
matches[n] = matches[i];
|
||||||
num_matches = n;
|
num_matches = n + 1;
|
||||||
}
|
}
|
||||||
/* Did we find exactly one match? */
|
/* Did we find exactly one match? */
|
||||||
if (!matches || num_matches > 1) {
|
if (!matches || num_matches > 1) {
|
||||||
@ -858,10 +844,10 @@ static void input_tab(int *lastWasTab)
|
|||||||
for (tmp = tmp1; *tmp; tmp++)
|
for (tmp = tmp1; *tmp; tmp++)
|
||||||
for (len_found = 1; len_found < num_matches; len_found++)
|
for (len_found = 1; len_found < num_matches; len_found++)
|
||||||
if (matches[len_found][(tmp - tmp1)] != *tmp) {
|
if (matches[len_found][(tmp - tmp1)] != *tmp) {
|
||||||
*tmp = 0;
|
*tmp = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*tmp1 == 0) { /* have unique */
|
if (*tmp1 == '\0') { /* have unique */
|
||||||
free(tmp1);
|
free(tmp1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -881,7 +867,6 @@ static void input_tab(int *lastWasTab)
|
|||||||
len_found = strlen(tmp);
|
len_found = strlen(tmp);
|
||||||
/* have space to placed match? */
|
/* have space to placed match? */
|
||||||
if ((len_found - strlen(matchBuf) + len) < BUFSIZ) {
|
if ((len_found - strlen(matchBuf) + len) < BUFSIZ) {
|
||||||
|
|
||||||
/* before word for match */
|
/* before word for match */
|
||||||
command_ps[cursor - recalc_pos] = 0;
|
command_ps[cursor - recalc_pos] = 0;
|
||||||
/* save tail line */
|
/* save tail line */
|
||||||
@ -914,6 +899,7 @@ static void input_tab(int *lastWasTab)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* FEATURE_COMMAND_TAB_COMPLETION */
|
#endif /* FEATURE_COMMAND_TAB_COMPLETION */
|
||||||
|
|
||||||
|
|
||||||
@ -927,7 +913,7 @@ static int cur_history;
|
|||||||
|
|
||||||
static void get_previous_history(void)
|
static void get_previous_history(void)
|
||||||
{
|
{
|
||||||
if (command_ps[0] != 0 || history[cur_history] == 0) {
|
if (command_ps[0] != '\0' || history[cur_history] == NULL) {
|
||||||
free(history[cur_history]);
|
free(history[cur_history]);
|
||||||
history[cur_history] = xstrdup(command_ps);
|
history[cur_history] = xstrdup(command_ps);
|
||||||
}
|
}
|
||||||
@ -1126,81 +1112,6 @@ enum { vi_mode = 0 };
|
|||||||
* cmdedit_read_input and its helpers
|
* cmdedit_read_input and its helpers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define setTermSettings(fd, argp) tcsetattr(fd, TCSANOW, argp)
|
|
||||||
#define getTermSettings(fd, argp) tcgetattr(fd, argp);
|
|
||||||
|
|
||||||
static sighandler_t previous_SIGWINCH_handler;
|
|
||||||
|
|
||||||
static void cmdedit_reset_term(void)
|
|
||||||
{
|
|
||||||
if (handlers_sets & SET_RESET_TERM) {
|
|
||||||
setTermSettings(STDIN_FILENO, (void *) &initial_settings);
|
|
||||||
handlers_sets &= ~SET_RESET_TERM;
|
|
||||||
}
|
|
||||||
if (handlers_sets & SET_WCHG_HANDLERS) {
|
|
||||||
/* restore SIGWINCH handler */
|
|
||||||
signal(SIGWINCH, previous_SIGWINCH_handler);
|
|
||||||
handlers_sets &= ~SET_WCHG_HANDLERS;
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cmdedit_setwidth(unsigned w, int redraw_flg)
|
|
||||||
{
|
|
||||||
cmdedit_termw = w;
|
|
||||||
if (redraw_flg) {
|
|
||||||
/* new y for current cursor */
|
|
||||||
int new_y = (cursor + cmdedit_prmt_len) / w;
|
|
||||||
/* redraw */
|
|
||||||
redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void win_changed(int nsig)
|
|
||||||
{
|
|
||||||
int width;
|
|
||||||
get_terminal_width_height(0, &width, NULL);
|
|
||||||
cmdedit_setwidth(width, nsig /* - just a yes/no flag */);
|
|
||||||
if (nsig == SIGWINCH)
|
|
||||||
signal(SIGWINCH, win_changed); /* rearm ourself */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cmdedit_init(void)
|
|
||||||
{
|
|
||||||
cmdedit_prmt_len = 0;
|
|
||||||
if (!(handlers_sets & SET_WCHG_HANDLERS)) {
|
|
||||||
previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
|
|
||||||
win_changed(0); /* do initial resizing */
|
|
||||||
handlers_sets |= SET_WCHG_HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(handlers_sets & SET_ATEXIT)) {
|
|
||||||
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
|
||||||
struct passwd *entry;
|
|
||||||
|
|
||||||
my_euid = geteuid();
|
|
||||||
entry = getpwuid(my_euid);
|
|
||||||
if (entry) {
|
|
||||||
user_buf = xstrdup(entry->pw_name);
|
|
||||||
home_pwd_buf = xstrdup(entry->pw_dir);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
|
||||||
|
|
||||||
#if !ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
|
||||||
my_euid = geteuid();
|
|
||||||
#endif
|
|
||||||
my_uid = getuid();
|
|
||||||
my_gid = getgid();
|
|
||||||
#endif /* FEATURE_COMMAND_TAB_COMPLETION */
|
|
||||||
handlers_sets |= SET_ATEXIT;
|
|
||||||
// Crap. We should be able to do it without atexit.
|
|
||||||
atexit(cmdedit_reset_term); /* be sure to do this only once */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !ENABLE_FEATURE_SH_FANCY_PROMPT
|
#if !ENABLE_FEATURE_SH_FANCY_PROMPT
|
||||||
static void parse_prompt(const char *prmt_ptr)
|
static void parse_prompt(const char *prmt_ptr)
|
||||||
{
|
{
|
||||||
@ -1259,7 +1170,7 @@ static void parse_prompt(const char *prmt_ptr)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '$':
|
case '$':
|
||||||
c = (my_euid == 0 ? '#' : '$');
|
c = (geteuid() == 0 ? '#' : '$');
|
||||||
break;
|
break;
|
||||||
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
||||||
case 'w':
|
case 'w':
|
||||||
@ -1283,7 +1194,8 @@ static void parse_prompt(const char *prmt_ptr)
|
|||||||
pbuf += (cp-pbuf) + 1;
|
pbuf += (cp-pbuf) + 1;
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!':
|
||||||
snprintf(pbuf = buf2, sizeof(buf2), "%d", num_ok_lines);
|
pbuf = buf2;
|
||||||
|
snprintf(buf2, sizeof(buf2), "%d", num_ok_lines);
|
||||||
break;
|
break;
|
||||||
case 'e': case 'E': /* \e \E = \033 */
|
case 'e': case 'E': /* \e \E = \033 */
|
||||||
c = '\033';
|
c = '\033';
|
||||||
@ -1330,11 +1242,71 @@ static void parse_prompt(const char *prmt_ptr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define setTermSettings(fd, argp) tcsetattr(fd, TCSANOW, argp)
|
||||||
|
#define getTermSettings(fd, argp) tcgetattr(fd, argp);
|
||||||
|
|
||||||
|
static sighandler_t previous_SIGWINCH_handler;
|
||||||
|
|
||||||
|
static void cmdedit_reset_term(void)
|
||||||
|
{
|
||||||
|
setTermSettings(STDIN_FILENO, (void *) &initial_settings);
|
||||||
|
/* restore SIGWINCH handler */
|
||||||
|
signal(SIGWINCH, previous_SIGWINCH_handler);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmdedit_setwidth(unsigned w, int redraw_flg)
|
||||||
|
{
|
||||||
|
cmdedit_termw = w;
|
||||||
|
if (redraw_flg) {
|
||||||
|
/* new y for current cursor */
|
||||||
|
int new_y = (cursor + cmdedit_prmt_len) / w;
|
||||||
|
/* redraw */
|
||||||
|
redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void win_changed(int nsig)
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
get_terminal_width_height(0, &width, NULL);
|
||||||
|
cmdedit_setwidth(width, nsig /* - just a yes/no flag */);
|
||||||
|
if (nsig == SIGWINCH)
|
||||||
|
signal(SIGWINCH, win_changed); /* rearm ourself */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmdedit_init(void)
|
||||||
|
{
|
||||||
|
cmdedit_prmt_len = 0;
|
||||||
|
previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
|
||||||
|
win_changed(0); /* do initial resizing */
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
||||||
|
{
|
||||||
|
struct passwd *entry;
|
||||||
|
|
||||||
|
entry = getpwuid(geteuid());
|
||||||
|
if (entry) {
|
||||||
|
user_buf = xstrdup(entry->pw_name);
|
||||||
|
home_pwd_buf = xstrdup(entry->pw_dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
||||||
|
my_uid = getuid();
|
||||||
|
my_gid = getgid();
|
||||||
|
#endif
|
||||||
|
// Crap. We should be able to do it without atexit.
|
||||||
|
atexit(cmdedit_reset_term); /* be sure to do this only once */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the emacs and vi modes share much of the code in the big
|
* The emacs and vi modes share much of the code in the big
|
||||||
* command loop. commands entered when in vi's command mode (aka
|
* command loop. Commands entered when in vi's command mode (aka
|
||||||
* "escape mode") get an extra bit added to distinguish them --
|
* "escape mode") get an extra bit added to distinguish them --
|
||||||
* this keeps them from being self-inserted. this clutters the
|
* this keeps them from being self-inserted. This clutters the
|
||||||
* big switch a bit, but keeps all the code in one place.
|
* big switch a bit, but keeps all the code in one place.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1379,7 +1351,6 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
|
|||||||
#endif
|
#endif
|
||||||
new_settings.c_cc[VINTR] = _POSIX_VDISABLE;
|
new_settings.c_cc[VINTR] = _POSIX_VDISABLE;
|
||||||
setTermSettings(0, (void *) &new_settings);
|
setTermSettings(0, (void *) &new_settings);
|
||||||
handlers_sets |= SET_RESET_TERM;
|
|
||||||
|
|
||||||
/* Now initialize things */
|
/* Now initialize things */
|
||||||
cmdedit_init();
|
cmdedit_init();
|
||||||
@ -1387,11 +1358,12 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
|
|||||||
parse_prompt(prompt);
|
parse_prompt(prompt);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
fflush(stdout); /* buffered out to fast */
|
fflush(stdout);
|
||||||
|
|
||||||
if (safe_read(0, &c, 1) < 1)
|
if (safe_read(0, &c, 1) < 1) {
|
||||||
/* if we can't read input then exit */
|
/* if we can't read input then exit */
|
||||||
goto prepare_to_die;
|
goto prepare_to_die;
|
||||||
|
}
|
||||||
|
|
||||||
ic = c;
|
ic = c;
|
||||||
|
|
||||||
@ -1789,23 +1761,22 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
|
|||||||
lastWasTab = FALSE;
|
lastWasTab = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTermSettings(0, (void *) &initial_settings);
|
|
||||||
handlers_sets &= ~SET_RESET_TERM;
|
|
||||||
|
|
||||||
#if MAX_HISTORY > 0
|
#if MAX_HISTORY > 0
|
||||||
/* Handle command history log */
|
/* Handle command history log */
|
||||||
/* cleanup may be saved current command line */
|
/* cleanup may be saved current command line */
|
||||||
if (len > 0) { /* no put empty line */
|
if (len > 0) {
|
||||||
int i = n_history;
|
int i = n_history;
|
||||||
|
|
||||||
free(history[MAX_HISTORY]);
|
free(history[MAX_HISTORY]);
|
||||||
history[MAX_HISTORY] = 0;
|
history[MAX_HISTORY] = NULL;
|
||||||
/* After max history, remove the oldest command */
|
/* After max history, remove the oldest command */
|
||||||
if (i >= MAX_HISTORY) {
|
if (i >= MAX_HISTORY) {
|
||||||
free(history[0]);
|
free(history[0]);
|
||||||
for (i = 0; i < MAX_HISTORY-1; i++)
|
for (i = 0; i < MAX_HISTORY-1; i++)
|
||||||
history[i] = history[i+1];
|
history[i] = history[i+1];
|
||||||
}
|
}
|
||||||
|
// Maybe "if (!i || strcmp(history[i-1], command) != 0) ..."
|
||||||
|
// (i.e. do not save dups?)
|
||||||
history[i++] = xstrdup(command);
|
history[i++] = xstrdup(command);
|
||||||
cur_history = i;
|
cur_history = i;
|
||||||
n_history = i;
|
n_history = i;
|
||||||
@ -1822,12 +1793,13 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
#if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION
|
||||||
input_tab(0);
|
free_tab_completion_data();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLE_FEATURE_SH_FANCY_PROMPT
|
#if ENABLE_FEATURE_SH_FANCY_PROMPT
|
||||||
free(cmdedit_prompt);
|
free(cmdedit_prompt);
|
||||||
#endif
|
#endif
|
||||||
|
/* restore initial_settings and SIGWINCH handler */
|
||||||
cmdedit_reset_term();
|
cmdedit_reset_term();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user