diff options
author | Ron Yorston <rmy@pobox.com> | 2019-12-16 09:04:08 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-12-16 09:04:08 +0000 |
commit | c0f40af509c4a4face7240e5dbabacaff02e669a (patch) | |
tree | 7335eb19df55691a3bcbf73e33ee4e00360b048c /shell | |
parent | 5957c8d7b4fc0dfe8def6036e182d3a40ba28cbe (diff) | |
download | busybox-w32-c0f40af509c4a4face7240e5dbabacaff02e669a.tar.gz busybox-w32-c0f40af509c4a4face7240e5dbabacaff02e669a.tar.bz2 busybox-w32-c0f40af509c4a4face7240e5dbabacaff02e669a.zip |
ash: copy line editing history during forkshell
Add code to store line editing history in the forkshell data block.
This allows things like 'history | grep whatever' to work.
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 104 |
1 files changed, 94 insertions, 10 deletions
diff --git a/shell/ash.c b/shell/ash.c index a45441877..8a27d5cc3 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -353,6 +353,10 @@ struct forkshell { | |||
353 | #if ENABLE_ASH_ALIAS | 353 | #if ENABLE_ASH_ALIAS |
354 | struct alias **atab; | 354 | struct alias **atab; |
355 | #endif | 355 | #endif |
356 | #if MAX_HISTORY | ||
357 | char **history; | ||
358 | int cnt_history; | ||
359 | #endif | ||
356 | /* struct parsefile *g_parsefile; */ | 360 | /* struct parsefile *g_parsefile; */ |
357 | HANDLE hMapFile; | 361 | HANDLE hMapFile; |
358 | char *old_base; | 362 | char *old_base; |
@@ -15743,6 +15747,38 @@ argv_copy(char **p) | |||
15743 | return start; | 15747 | return start; |
15744 | } | 15748 | } |
15745 | 15749 | ||
15750 | #if MAX_HISTORY | ||
15751 | static int | ||
15752 | history_size(int funcblocksize, line_input_t *st) | ||
15753 | { | ||
15754 | int i; | ||
15755 | |||
15756 | funcblocksize += sizeof(char *) * st->cnt_history; | ||
15757 | for (i = 0; i < st->cnt_history; i++) { | ||
15758 | funcblocksize += align_len(st->history[i]); | ||
15759 | } | ||
15760 | nodeptrcount += st->cnt_history; | ||
15761 | return funcblocksize; | ||
15762 | } | ||
15763 | |||
15764 | static char ** | ||
15765 | history_copy(line_input_t *st) | ||
15766 | { | ||
15767 | char **new, **start = funcblock; | ||
15768 | int i; | ||
15769 | |||
15770 | for (i = 0; i < st->cnt_history; i++) { | ||
15771 | new = funcblock; | ||
15772 | funcblock = (char *) funcblock + sizeof(char *); | ||
15773 | *new = nodeckstrdup(st->history[i]); | ||
15774 | SAVE_PTR(*new); | ||
15775 | ANNOT_NO_DUP(xasprintf("history[%d] '%s'", i, st->history[i])); | ||
15776 | new++; | ||
15777 | } | ||
15778 | return start; | ||
15779 | } | ||
15780 | #endif | ||
15781 | |||
15746 | /* | 15782 | /* |
15747 | * struct redirtab | 15783 | * struct redirtab |
15748 | */ | 15784 | */ |
@@ -15891,6 +15927,13 @@ forkshell_size(int funcblocksize, struct forkshell *fs) | |||
15891 | #else | 15927 | #else |
15892 | nodeptrcount += 7; /* gvp, gmp, cmdtable, n, argv, string, strlist */ | 15928 | nodeptrcount += 7; /* gvp, gmp, cmdtable, n, argv, string, strlist */ |
15893 | #endif | 15929 | #endif |
15930 | |||
15931 | #if MAX_HISTORY | ||
15932 | if (line_input_state) { | ||
15933 | funcblocksize = history_size(funcblocksize, line_input_state); | ||
15934 | nodeptrcount++; /* history */ | ||
15935 | } | ||
15936 | #endif | ||
15894 | return funcblocksize; | 15937 | return funcblocksize; |
15895 | } | 15938 | } |
15896 | 15939 | ||
@@ -15918,6 +15961,15 @@ forkshell_copy(struct forkshell *fs, struct forkshell *new) | |||
15918 | ANNOT2("n", "argv"); | 15961 | ANNOT2("n", "argv"); |
15919 | ANNOT_NO_DUP(xasprintf("path '%s'", fs->path ?: "NULL")); | 15962 | ANNOT_NO_DUP(xasprintf("path '%s'", fs->path ?: "NULL")); |
15920 | ANNOT("varlist"); | 15963 | ANNOT("varlist"); |
15964 | |||
15965 | #if MAX_HISTORY | ||
15966 | if (line_input_state) { | ||
15967 | new->history = history_copy(line_input_state); | ||
15968 | SAVE_PTR(new->history); | ||
15969 | ANNOT("history"); | ||
15970 | new->cnt_history = line_input_state->cnt_history; | ||
15971 | } | ||
15972 | #endif | ||
15921 | } | 15973 | } |
15922 | 15974 | ||
15923 | #if FORKSHELL_DEBUG | 15975 | #if FORKSHELL_DEBUG |
@@ -15931,6 +15983,7 @@ forkshell_print(FILE *fp0, struct forkshell *fs, char **notes) | |||
15931 | char ***lnodeptr; | 15983 | char ***lnodeptr; |
15932 | char *s; | 15984 | char *s; |
15933 | int count; | 15985 | int count; |
15986 | int size_gvp, size_gmp, size_cmdtable, size_atab, size_history, total; | ||
15934 | 15987 | ||
15935 | if (fp0 != NULL) { | 15988 | if (fp0 != NULL) { |
15936 | fp = fp0; | 15989 | fp = fp0; |
@@ -15951,18 +16004,41 @@ forkshell_print(FILE *fp0, struct forkshell *fs, char **notes) | |||
15951 | lfuncblock = (char *)lnodeptr + (fs->nodeptrcount+1)*sizeof(char *); | 16004 | lfuncblock = (char *)lnodeptr + (fs->nodeptrcount+1)*sizeof(char *); |
15952 | lfuncstring = (char *)lfuncblock + fs->funcblocksize; | 16005 | lfuncstring = (char *)lfuncblock + fs->funcblocksize; |
15953 | 16006 | ||
15954 | #if ENABLE_ASH_ALIAS | 16007 | size_gvp = (int)((char *)fs->gmp-(char *)fs->gvp); |
15955 | fprintf(fp, "funcblocksize %d = %d + %d + %d + %d\n\n", fs->funcblocksize, | 16008 | size_gmp = (int)((char *)fs->cmdtable-(char *)fs->gmp); |
15956 | (int)((char *)fs->gmp-(char *)fs->gvp), | 16009 | #if ENABLE_ASH_ALIAS && MAX_HISTORY |
15957 | (int)((char *)fs->cmdtable-(char *)fs->gmp), | 16010 | size_cmdtable = (int)((char *)fs->atab-(char *)fs->cmdtable); |
15958 | (int)((char *)fs->atab-(char *)fs->cmdtable), | 16011 | if (fs->history) { |
15959 | (int)(lfuncstring-(char *)fs->atab)); | 16012 | size_atab = (int)((char *)fs->history-(char *)fs->atab); |
16013 | size_history = (int)(lfuncstring-(char *)fs->history); | ||
16014 | } | ||
16015 | else { | ||
16016 | size_atab = (int)(lfuncstring-(char *)fs->atab); | ||
16017 | size_history = 0; | ||
16018 | } | ||
16019 | #elif ENABLE_ASH_ALIAS | ||
16020 | size_cmdtable = (int)((char *)fs->atab-(char *)fs->cmdtable); | ||
16021 | size_atab = (int)(lfuncstring-(char *)fs->atab); | ||
16022 | size_history = 0; | ||
16023 | #elif MAX_HISTORY | ||
16024 | size_atab = 0; | ||
16025 | if (fs->history) { | ||
16026 | size_cmdtable = (int)((char *)fs->history-(char *)fs->cmdtable); | ||
16027 | size_history = (int)(lfuncstring-(char *)fs->history); | ||
16028 | } | ||
16029 | else { | ||
16030 | size_cmdtable = (int)(lfuncstring-(char *)fs->cmdtable); | ||
16031 | size_history = 0; | ||
16032 | } | ||
15960 | #else | 16033 | #else |
15961 | fprintf(fp, "funcblocksize %d = %d + %d + %d\n\n", fs->funcblocksize, | 16034 | size_cmdtable = (int)(lfuncstring-(char *)fs->cmdtable); |
15962 | (int)((char *)fs->gmp-(char *)fs->gvp), | 16035 | size_atab = 0; |
15963 | (int)((char *)fs->cmdtable-(char *)fs->gmp), | 16036 | size_history = 0; |
15964 | (int)(lfuncstring-(char *)fs->cmdtable)); | ||
15965 | #endif | 16037 | #endif |
16038 | total = size_gvp + size_gmp + size_cmdtable + size_atab + size_history; | ||
16039 | fprintf(fp, "funcblocksize %d = %d + %d + %d + %d + %d = %d\n\n", | ||
16040 | fs->funcblocksize, size_gvp, size_gmp, size_cmdtable, | ||
16041 | size_atab, size_history, total); | ||
15966 | 16042 | ||
15967 | fprintf(fp, "--- nodeptr ---\n"); | 16043 | fprintf(fp, "--- nodeptr ---\n"); |
15968 | count = 0; | 16044 | count = 0; |
@@ -16160,6 +16236,14 @@ forkshell_init(const char *idstr) | |||
16160 | #if ENABLE_ASH_ALIAS | 16236 | #if ENABLE_ASH_ALIAS |
16161 | atab = fs->atab; | 16237 | atab = fs->atab; |
16162 | #endif | 16238 | #endif |
16239 | #if MAX_HISTORY | ||
16240 | if (fs->cnt_history) { | ||
16241 | line_input_state = new_line_input_t(FOR_SHELL); | ||
16242 | line_input_state->cnt_history = fs->cnt_history; | ||
16243 | for (i = 0; i < line_input_state->cnt_history; i++) | ||
16244 | line_input_state->history[i] = fs->history[i]; | ||
16245 | } | ||
16246 | #endif | ||
16163 | 16247 | ||
16164 | CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */ | 16248 | CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */ |
16165 | 16249 | ||