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 | ||
