aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-12-16 09:04:08 +0000
committerRon Yorston <rmy@pobox.com>2019-12-16 09:04:08 +0000
commitc0f40af509c4a4face7240e5dbabacaff02e669a (patch)
tree7335eb19df55691a3bcbf73e33ee4e00360b048c /shell
parent5957c8d7b4fc0dfe8def6036e182d3a40ba28cbe (diff)
downloadbusybox-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.c104
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
15751static int
15752history_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
15764static char **
15765history_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