diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/Kbuild | 10 | ||||
-rw-r--r-- | shell/ash.c | 106 | ||||
-rw-r--r-- | shell/cmdedit.c | 316 | ||||
-rw-r--r-- | shell/cmdedit.h | 21 | ||||
-rw-r--r-- | shell/hush.c | 13 | ||||
-rw-r--r-- | shell/lash.c | 14 | ||||
-rw-r--r-- | shell/msh.c | 26 |
7 files changed, 251 insertions, 255 deletions
diff --git a/shell/Kbuild b/shell/Kbuild index eb0199ee2..9c60698f7 100644 --- a/shell/Kbuild +++ b/shell/Kbuild | |||
@@ -5,8 +5,8 @@ | |||
5 | # Licensed under the GPL v2, see the file LICENSE in this tarball. | 5 | # Licensed under the GPL v2, see the file LICENSE in this tarball. |
6 | 6 | ||
7 | lib-y:= | 7 | lib-y:= |
8 | lib-$(CONFIG_ASH) += ash.o | 8 | lib-y += cmdedit.o |
9 | lib-$(CONFIG_HUSH) += hush.o | 9 | lib-$(CONFIG_ASH) += ash.o |
10 | lib-$(CONFIG_LASH) += lash.o | 10 | lib-$(CONFIG_HUSH) += hush.o |
11 | lib-$(CONFIG_MSH) += msh.o | 11 | lib-$(CONFIG_LASH) += lash.o |
12 | lib-$(CONFIG_FEATURE_COMMAND_EDITING) += cmdedit.o | 12 | lib-$(CONFIG_MSH) += msh.o |
diff --git a/shell/ash.c b/shell/ash.c index 2db3302c7..8afdf3d21 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -92,7 +92,6 @@ | |||
92 | #include <termios.h> | 92 | #include <termios.h> |
93 | #endif | 93 | #endif |
94 | 94 | ||
95 | #include "cmdedit.h" | ||
96 | 95 | ||
97 | #ifdef __GLIBC__ | 96 | #ifdef __GLIBC__ |
98 | /* glibc sucks */ | 97 | /* glibc sucks */ |
@@ -1238,7 +1237,7 @@ static int fgcmd(int, char **); | |||
1238 | static int getoptscmd(int, char **); | 1237 | static int getoptscmd(int, char **); |
1239 | #endif | 1238 | #endif |
1240 | static int hashcmd(int, char **); | 1239 | static int hashcmd(int, char **); |
1241 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 1240 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
1242 | static int helpcmd(int argc, char **argv); | 1241 | static int helpcmd(int argc, char **argv); |
1243 | #endif | 1242 | #endif |
1244 | #if JOBS | 1243 | #if JOBS |
@@ -1347,7 +1346,7 @@ static const struct builtincmd builtincmd[] = { | |||
1347 | { BUILTIN_REGULAR "getopts", getoptscmd }, | 1346 | { BUILTIN_REGULAR "getopts", getoptscmd }, |
1348 | #endif | 1347 | #endif |
1349 | { BUILTIN_NOSPEC "hash", hashcmd }, | 1348 | { BUILTIN_NOSPEC "hash", hashcmd }, |
1350 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 1349 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
1351 | { BUILTIN_NOSPEC "help", helpcmd }, | 1350 | { BUILTIN_NOSPEC "help", helpcmd }, |
1352 | #endif | 1351 | #endif |
1353 | #if JOBS | 1352 | #if JOBS |
@@ -1529,7 +1528,7 @@ static struct var varinit[] = { | |||
1529 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all }, | 1528 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all }, |
1530 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype }, | 1529 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype }, |
1531 | #endif | 1530 | #endif |
1532 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | 1531 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY |
1533 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL }, | 1532 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL }, |
1534 | #endif | 1533 | #endif |
1535 | }; | 1534 | }; |
@@ -1934,10 +1933,6 @@ struct shparam { | |||
1934 | #define debug optlist[15] | 1933 | #define debug optlist[15] |
1935 | #endif | 1934 | #endif |
1936 | 1935 | ||
1937 | #ifndef CONFIG_FEATURE_COMMAND_EDITING_VI | ||
1938 | #define setvimode(on) viflag = 0 /* forcibly keep the option off */ | ||
1939 | #endif | ||
1940 | |||
1941 | /* options.c */ | 1936 | /* options.c */ |
1942 | 1937 | ||
1943 | 1938 | ||
@@ -3718,7 +3713,7 @@ shellexec(char **argv, const char *path, int idx) | |||
3718 | clearredir(1); | 3713 | clearredir(1); |
3719 | envp = environment(); | 3714 | envp = environment(); |
3720 | if (strchr(argv[0], '/') || is_safe_applet(argv[0]) | 3715 | if (strchr(argv[0], '/') || is_safe_applet(argv[0]) |
3721 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 3716 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
3722 | || find_applet_by_name(argv[0]) | 3717 | || find_applet_by_name(argv[0]) |
3723 | #endif | 3718 | #endif |
3724 | ) { | 3719 | ) { |
@@ -3775,7 +3770,7 @@ tryexec(char *cmd, char **argv, char **envp) | |||
3775 | applet_name = cmd; | 3770 | applet_name = cmd; |
3776 | exit(a->main(argc, argv)); | 3771 | exit(a->main(argc, argv)); |
3777 | } | 3772 | } |
3778 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 3773 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
3779 | if (find_applet_by_name(cmd) != NULL) { | 3774 | if (find_applet_by_name(cmd) != NULL) { |
3780 | /* re-exec ourselves with the new arguments */ | 3775 | /* re-exec ourselves with the new arguments */ |
3781 | execve(CONFIG_BUSYBOX_EXEC_PATH,argv,envp); | 3776 | execve(CONFIG_BUSYBOX_EXEC_PATH,argv,envp); |
@@ -3949,7 +3944,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) | |||
3949 | return; | 3944 | return; |
3950 | } | 3945 | } |
3951 | 3946 | ||
3952 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 3947 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
3953 | if (find_applet_by_name(name)) { | 3948 | if (find_applet_by_name(name)) { |
3954 | entry->cmdtype = CMDNORMAL; | 3949 | entry->cmdtype = CMDNORMAL; |
3955 | entry->u.index = -1; | 3950 | entry->u.index = -1; |
@@ -6045,21 +6040,18 @@ static char * pfgets(char *line, int len) | |||
6045 | } | 6040 | } |
6046 | 6041 | ||
6047 | 6042 | ||
6048 | 6043 | #if ENABLE_FEATURE_COMMAND_EDITING | |
6049 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 6044 | static line_input_t *line_input_state; |
6050 | #ifdef CONFIG_ASH_EXPAND_PRMT | 6045 | //static SKIP_ASH_EXPAND_PRMT(const) char *cmdedit_prompt; |
6051 | static char *cmdedit_prompt; | ||
6052 | #else | ||
6053 | static const char *cmdedit_prompt; | 6046 | static const char *cmdedit_prompt; |
6054 | #endif | ||
6055 | static void putprompt(const char *s) | 6047 | static void putprompt(const char *s) |
6056 | { | 6048 | { |
6057 | #ifdef CONFIG_ASH_EXPAND_PRMT | 6049 | if (ENABLE_ASH_EXPAND_PRMT) { |
6058 | free(cmdedit_prompt); | 6050 | free((char*)cmdedit_prompt); |
6059 | cmdedit_prompt = xstrdup(s); | 6051 | cmdedit_prompt = xstrdup(s); |
6060 | #else | 6052 | return; |
6053 | } | ||
6061 | cmdedit_prompt = s; | 6054 | cmdedit_prompt = s; |
6062 | #endif | ||
6063 | } | 6055 | } |
6064 | #else | 6056 | #else |
6065 | static void putprompt(const char *s) | 6057 | static void putprompt(const char *s) |
@@ -6068,6 +6060,16 @@ static void putprompt(const char *s) | |||
6068 | } | 6060 | } |
6069 | #endif | 6061 | #endif |
6070 | 6062 | ||
6063 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | ||
6064 | #define setvimode(on) do { \ | ||
6065 | if (on) line_input_state->flags |= VI_MODE; \ | ||
6066 | else line_input_state->flags &= ~VI_MODE; \ | ||
6067 | } while (0) | ||
6068 | #else | ||
6069 | #define setvimode(on) viflag = 0 /* forcibly keep the option off */ | ||
6070 | #endif | ||
6071 | |||
6072 | |||
6071 | static int preadfd(void) | 6073 | static int preadfd(void) |
6072 | { | 6074 | { |
6073 | int nr; | 6075 | int nr; |
@@ -6075,25 +6077,25 @@ static int preadfd(void) | |||
6075 | parsenextc = buf; | 6077 | parsenextc = buf; |
6076 | 6078 | ||
6077 | retry: | 6079 | retry: |
6078 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 6080 | #if ENABLE_FEATURE_COMMAND_EDITING |
6079 | if (!iflag || parsefile->fd) | 6081 | if (!iflag || parsefile->fd) |
6080 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); | 6082 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); |
6081 | else { | 6083 | else { |
6082 | #ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION | 6084 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION |
6083 | cmdedit_path_lookup = pathval(); | 6085 | line_input_state->path_lookup = pathval(); |
6084 | #endif | 6086 | #endif |
6085 | nr = cmdedit_read_input((char *) cmdedit_prompt, buf); | 6087 | nr = read_line_input(cmdedit_prompt, buf, BUFSIZ, line_input_state); |
6086 | if(nr == 0) { | 6088 | if (nr == 0) { |
6087 | /* Ctrl+C presend */ | 6089 | /* Ctrl+C pressed */ |
6088 | if(trap[SIGINT]) { | 6090 | if (trap[SIGINT]) { |
6089 | buf[0] = '\n'; | 6091 | buf[0] = '\n'; |
6090 | buf[1] = 0; | 6092 | buf[1] = '\0'; |
6091 | raise(SIGINT); | 6093 | raise(SIGINT); |
6092 | return 1; | 6094 | return 1; |
6093 | } | 6095 | } |
6094 | goto retry; | 6096 | goto retry; |
6095 | } | 6097 | } |
6096 | if(nr < 0 && errno == 0) { | 6098 | if (nr < 0 && errno == 0) { |
6097 | /* Ctrl+D presend */ | 6099 | /* Ctrl+D presend */ |
6098 | nr = 0; | 6100 | nr = 0; |
6099 | } | 6101 | } |
@@ -7913,6 +7915,10 @@ ash_main(int argc, char **argv) | |||
7913 | #if PROFILE | 7915 | #if PROFILE |
7914 | monitor(4, etext, profile_buf, sizeof profile_buf, 50); | 7916 | monitor(4, etext, profile_buf, sizeof profile_buf, 50); |
7915 | #endif | 7917 | #endif |
7918 | |||
7919 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
7920 | line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); | ||
7921 | #endif | ||
7916 | state = 0; | 7922 | state = 0; |
7917 | if (setjmp(jmploc.loc)) { | 7923 | if (setjmp(jmploc.loc)) { |
7918 | int e; | 7924 | int e; |
@@ -7954,11 +7960,11 @@ ash_main(int argc, char **argv) | |||
7954 | init(); | 7960 | init(); |
7955 | setstackmark(&smark); | 7961 | setstackmark(&smark); |
7956 | procargs(argc, argv); | 7962 | procargs(argc, argv); |
7957 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | 7963 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY |
7958 | if ( iflag ) { | 7964 | if (iflag) { |
7959 | const char *hp = lookupvar("HISTFILE"); | 7965 | const char *hp = lookupvar("HISTFILE"); |
7960 | 7966 | ||
7961 | if(hp == NULL ) { | 7967 | if (hp == NULL) { |
7962 | hp = lookupvar("HOME"); | 7968 | hp = lookupvar("HOME"); |
7963 | if(hp != NULL) { | 7969 | if(hp != NULL) { |
7964 | char *defhp = concat_path_file(hp, ".ash_history"); | 7970 | char *defhp = concat_path_file(hp, ".ash_history"); |
@@ -7995,15 +8001,15 @@ state3: | |||
7995 | evalstring(minusc, 0); | 8001 | evalstring(minusc, 0); |
7996 | 8002 | ||
7997 | if (sflag || minusc == NULL) { | 8003 | if (sflag || minusc == NULL) { |
7998 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | 8004 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY |
7999 | if ( iflag ) { | 8005 | if ( iflag ) { |
8000 | const char *hp = lookupvar("HISTFILE"); | 8006 | const char *hp = lookupvar("HISTFILE"); |
8001 | 8007 | ||
8002 | if(hp != NULL ) | 8008 | if (hp != NULL) |
8003 | load_history ( hp ); | 8009 | line_input_state->hist_file = hp; |
8004 | } | 8010 | } |
8005 | #endif | 8011 | #endif |
8006 | state4: /* XXX ??? - why isn't this before the "if" statement */ | 8012 | state4: /* XXX ??? - why isn't this before the "if" statement */ |
8007 | cmdloop(1); | 8013 | cmdloop(1); |
8008 | } | 8014 | } |
8009 | #if PROFILE | 8015 | #if PROFILE |
@@ -11880,7 +11886,7 @@ setinteractive(int on) | |||
11880 | setsignal(SIGINT); | 11886 | setsignal(SIGINT); |
11881 | setsignal(SIGQUIT); | 11887 | setsignal(SIGQUIT); |
11882 | setsignal(SIGTERM); | 11888 | setsignal(SIGTERM); |
11883 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 11889 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
11884 | if(is_interactive > 1) { | 11890 | if(is_interactive > 1) { |
11885 | /* Looks like they want an interactive shell */ | 11891 | /* Looks like they want an interactive shell */ |
11886 | static int do_banner; | 11892 | static int do_banner; |
@@ -11897,7 +11903,7 @@ setinteractive(int on) | |||
11897 | } | 11903 | } |
11898 | 11904 | ||
11899 | 11905 | ||
11900 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 11906 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
11901 | /*** List the available builtins ***/ | 11907 | /*** List the available builtins ***/ |
11902 | 11908 | ||
11903 | static int helpcmd(int argc, char **argv) | 11909 | static int helpcmd(int argc, char **argv) |
@@ -11913,7 +11919,7 @@ static int helpcmd(int argc, char **argv) | |||
11913 | col = 0; | 11919 | col = 0; |
11914 | } | 11920 | } |
11915 | } | 11921 | } |
11916 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 11922 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
11917 | for (i = 0; i < NUM_APPLETS; i++) { | 11923 | for (i = 0; i < NUM_APPLETS; i++) { |
11918 | col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name); | 11924 | col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name); |
11919 | if (col > 60) { | 11925 | if (col > 60) { |
@@ -11945,7 +11951,7 @@ exitshell(void) | |||
11945 | /* dash bug: it just does _exit(exitstatus) here | 11951 | /* dash bug: it just does _exit(exitstatus) here |
11946 | * but we have to do setjobctl(0) first! | 11952 | * but we have to do setjobctl(0) first! |
11947 | * (bug is still not fixed in dash-0.5.3 - if you run dash | 11953 | * (bug is still not fixed in dash-0.5.3 - if you run dash |
11948 | * under Midnight Commander, on exit MC is backgrounded) */ | 11954 | * under Midnight Commander, on exit from dash MC is backgrounded) */ |
11949 | status = exitstatus; | 11955 | status = exitstatus; |
11950 | goto out; | 11956 | goto out; |
11951 | } | 11957 | } |
@@ -11955,14 +11961,6 @@ exitshell(void) | |||
11955 | evalstring(p, 0); | 11961 | evalstring(p, 0); |
11956 | } | 11962 | } |
11957 | flushall(); | 11963 | flushall(); |
11958 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | ||
11959 | if (iflag && rootshell) { | ||
11960 | const char *hp = lookupvar("HISTFILE"); | ||
11961 | |||
11962 | if (hp != NULL) | ||
11963 | save_history(hp); | ||
11964 | } | ||
11965 | #endif | ||
11966 | out: | 11964 | out: |
11967 | setjobctl(0); | 11965 | setjobctl(0); |
11968 | _exit(status); | 11966 | _exit(status); |
@@ -13491,7 +13489,7 @@ static const char op_tokens[] = { | |||
13491 | #define endexpression &op_tokens[sizeof(op_tokens)-7] | 13489 | #define endexpression &op_tokens[sizeof(op_tokens)-7] |
13492 | 13490 | ||
13493 | 13491 | ||
13494 | static arith_t arith (const char *expr, int *perrcode) | 13492 | static arith_t arith(const char *expr, int *perrcode) |
13495 | { | 13493 | { |
13496 | char arithval; /* Current character under analysis */ | 13494 | char arithval; /* Current character under analysis */ |
13497 | operator lasttok, op; | 13495 | operator lasttok, op; |
diff --git a/shell/cmdedit.c b/shell/cmdedit.c index a1432af15..554a4ebec 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c | |||
@@ -30,7 +30,6 @@ | |||
30 | 30 | ||
31 | #include <sys/ioctl.h> | 31 | #include <sys/ioctl.h> |
32 | #include "busybox.h" | 32 | #include "busybox.h" |
33 | #include "cmdedit.h" | ||
34 | 33 | ||
35 | 34 | ||
36 | /* FIXME: obsolete CONFIG item? */ | 35 | /* FIXME: obsolete CONFIG item? */ |
@@ -51,7 +50,6 @@ | |||
51 | /* Entire file (except TESTing part) sits inside this #if */ | 50 | /* Entire file (except TESTing part) sits inside this #if */ |
52 | #if ENABLE_FEATURE_COMMAND_EDITING | 51 | #if ENABLE_FEATURE_COMMAND_EDITING |
53 | 52 | ||
54 | |||
55 | #if ENABLE_LOCALE_SUPPORT | 53 | #if ENABLE_LOCALE_SUPPORT |
56 | #define Isprint(c) isprint(c) | 54 | #define Isprint(c) isprint(c) |
57 | #else | 55 | #else |
@@ -61,29 +59,21 @@ | |||
61 | #define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ | 59 | #define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ |
62 | (ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION || ENABLE_FEATURE_SH_FANCY_PROMPT) | 60 | (ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION || ENABLE_FEATURE_SH_FANCY_PROMPT) |
63 | 61 | ||
64 | /* Maximum length of command line history */ | ||
65 | #if !ENABLE_FEATURE_COMMAND_HISTORY | ||
66 | #define MAX_HISTORY 15 | ||
67 | #else | ||
68 | #define MAX_HISTORY (CONFIG_FEATURE_COMMAND_HISTORY + 0) | ||
69 | #endif | ||
70 | 62 | ||
63 | static line_input_t *state; | ||
71 | 64 | ||
72 | /* Current termios and the previous termios before starting sh */ | ||
73 | static struct termios initial_settings, new_settings; | 65 | static struct termios initial_settings, new_settings; |
74 | 66 | ||
75 | static | 67 | static volatile unsigned cmdedit_termw = 80; /* actual terminal width */ |
76 | volatile unsigned cmdedit_termw = 80; /* actual terminal width */ | ||
77 | |||
78 | 68 | ||
79 | static int cmdedit_x; /* real x terminal position */ | 69 | static int cmdedit_x; /* real x terminal position */ |
80 | static int cmdedit_y; /* pseudoreal y terminal position */ | 70 | static int cmdedit_y; /* pseudoreal y terminal position */ |
81 | static int cmdedit_prmt_len; /* length of prompt (without colors etc) */ | 71 | static int cmdedit_prmt_len; /* length of prompt (without colors etc) */ |
82 | 72 | ||
83 | static int cursor; | 73 | static unsigned cursor; |
84 | static int len; | 74 | static unsigned command_len; |
85 | static char *command_ps; | 75 | static char *command_ps; |
86 | static SKIP_FEATURE_SH_FANCY_PROMPT(const) char *cmdedit_prompt; | 76 | static const char *cmdedit_prompt; |
87 | 77 | ||
88 | #if ENABLE_FEATURE_SH_FANCY_PROMPT | 78 | #if ENABLE_FEATURE_SH_FANCY_PROMPT |
89 | static char *hostname_buf; | 79 | static char *hostname_buf; |
@@ -142,7 +132,7 @@ static void cmdedit_set_out_char(int next_char) | |||
142 | /* Move to end of line (by printing all chars till the end) */ | 132 | /* Move to end of line (by printing all chars till the end) */ |
143 | static void input_end(void) | 133 | static void input_end(void) |
144 | { | 134 | { |
145 | while (cursor < len) | 135 | while (cursor < command_len) |
146 | cmdedit_set_out_char(' '); | 136 | cmdedit_set_out_char(' '); |
147 | } | 137 | } |
148 | 138 | ||
@@ -200,7 +190,7 @@ static void input_backward(unsigned num) | |||
200 | static void put_prompt(void) | 190 | static void put_prompt(void) |
201 | { | 191 | { |
202 | out1str(cmdedit_prompt); | 192 | out1str(cmdedit_prompt); |
203 | cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */ | 193 | cmdedit_x = cmdedit_prmt_len; |
204 | cursor = 0; | 194 | cursor = 0; |
205 | // Huh? what if cmdedit_prmt_len >= width? | 195 | // Huh? what if cmdedit_prmt_len >= width? |
206 | cmdedit_y = 0; /* new quasireal y */ | 196 | cmdedit_y = 0; /* new quasireal y */ |
@@ -231,7 +221,7 @@ static void input_delete(int save) | |||
231 | { | 221 | { |
232 | int j = cursor; | 222 | int j = cursor; |
233 | 223 | ||
234 | if (j == len) | 224 | if (j == command_len) |
235 | return; | 225 | return; |
236 | 226 | ||
237 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | 227 | #if ENABLE_FEATURE_COMMAND_EDITING_VI |
@@ -249,7 +239,7 @@ static void input_delete(int save) | |||
249 | #endif | 239 | #endif |
250 | 240 | ||
251 | strcpy(command_ps + j, command_ps + j + 1); | 241 | strcpy(command_ps + j, command_ps + j + 1); |
252 | len--; | 242 | command_len--; |
253 | input_end(); /* rewrite new line */ | 243 | input_end(); /* rewrite new line */ |
254 | cmdedit_set_out_char(' '); /* erase char */ | 244 | cmdedit_set_out_char(' '); /* erase char */ |
255 | input_backward(cursor - j); /* back to old pos cursor */ | 245 | input_backward(cursor - j); /* back to old pos cursor */ |
@@ -285,7 +275,7 @@ static void input_backspace(void) | |||
285 | /* Move forward one character */ | 275 | /* Move forward one character */ |
286 | static void input_forward(void) | 276 | static void input_forward(void) |
287 | { | 277 | { |
288 | if (cursor < len) | 278 | if (cursor < command_len) |
289 | cmdedit_set_out_char(command_ps[cursor + 1]); | 279 | cmdedit_set_out_char(command_ps[cursor + 1]); |
290 | } | 280 | } |
291 | 281 | ||
@@ -372,54 +362,50 @@ enum { | |||
372 | FIND_FILE_ONLY = 2, | 362 | FIND_FILE_ONLY = 2, |
373 | }; | 363 | }; |
374 | 364 | ||
375 | #if ENABLE_ASH | ||
376 | const char *cmdedit_path_lookup; | ||
377 | #endif | ||
378 | static int path_parse(char ***p, int flags) | 365 | static int path_parse(char ***p, int flags) |
379 | { | 366 | { |
380 | int npth; | 367 | int npth; |
381 | const char *tmp; | 368 | const char *tmp; |
382 | #if ENABLE_ASH | 369 | const char *pth; |
383 | const char *pth = cmdedit_path_lookup; | 370 | char **res; |
384 | #else | ||
385 | const char *pth = getenv("PATH") | ||
386 | #endif | ||
387 | 371 | ||
388 | /* if not setenv PATH variable, to search cur dir "." */ | 372 | /* if not setenv PATH variable, to search cur dir "." */ |
389 | if (flags != FIND_EXE_ONLY) | 373 | if (flags != FIND_EXE_ONLY) |
390 | return 1; | 374 | return 1; |
375 | |||
376 | if (state->flags & WITH_PATH_LOOKUP) | ||
377 | pth = state->path_lookup; | ||
378 | else | ||
379 | pth = getenv("PATH"); | ||
391 | /* PATH=<empty> or PATH=:<empty> */ | 380 | /* PATH=<empty> or PATH=:<empty> */ |
392 | if (!pth || !pth[0] || LONE_CHAR(pth, ':')) | 381 | if (!pth || !pth[0] || LONE_CHAR(pth, ':')) |
393 | return 1; | 382 | return 1; |
394 | 383 | ||
395 | tmp = pth; | 384 | tmp = pth; |
396 | npth = 0; | 385 | npth = 1; /* path component count */ |
397 | |||
398 | while (1) { | 386 | while (1) { |
399 | npth++; /* count words is + 1 count ':' */ | ||
400 | tmp = strchr(tmp, ':'); | 387 | tmp = strchr(tmp, ':'); |
401 | if (!tmp) | 388 | if (!tmp) |
402 | break; | 389 | break; |
403 | if (*++tmp == '\0') | 390 | if (*++tmp == '\0') |
404 | break; /* :<empty> */ | 391 | break; /* :<empty> */ |
392 | npth++; | ||
405 | } | 393 | } |
406 | 394 | ||
407 | *p = xmalloc(npth * sizeof(char *)); | 395 | res = xmalloc(npth * sizeof(char*)); |
408 | 396 | res[0] = xstrdup(pth); | |
409 | tmp = pth; | 397 | tmp = pth; |
410 | (*p)[0] = xstrdup(tmp); | 398 | npth = 1; |
411 | npth = 1; /* count words is + 1 count ':' */ | ||
412 | |||
413 | while (1) { | 399 | while (1) { |
414 | tmp = strchr(tmp, ':'); | 400 | tmp = strchr(tmp, ':'); |
415 | if (!tmp) | 401 | if (!tmp) |
416 | break; | 402 | break; |
417 | (*p)[0][(tmp - pth)] = 0; /* ':' -> '\0' */ | 403 | *tmp++ = '\0'; /* ':' -> '\0' */ |
418 | if (*++tmp == 0) | 404 | if (*tmp == '\0') |
419 | break; /* :<empty> */ | 405 | break; /* :<empty> */ |
420 | (*p)[npth++] = &(*p)[0][(tmp - pth)]; /* p[next]=p[0][&'\0'+1] */ | 406 | res[npth++] = tmp; |
421 | } | 407 | } |
422 | 408 | *p = res; | |
423 | return npth; | 409 | return npth; |
424 | } | 410 | } |
425 | 411 | ||
@@ -742,6 +728,9 @@ static int match_compare(const void *a, const void *b) | |||
742 | /* Do TAB completion */ | 728 | /* Do TAB completion */ |
743 | static void input_tab(int *lastWasTab) | 729 | static void input_tab(int *lastWasTab) |
744 | { | 730 | { |
731 | if (!(state->flags & TAB_COMPLETION)) | ||
732 | return; | ||
733 | |||
745 | if (!*lastWasTab) { | 734 | if (!*lastWasTab) { |
746 | char *tmp, *tmp1; | 735 | char *tmp, *tmp1; |
747 | int len_found; | 736 | int len_found; |
@@ -764,13 +753,13 @@ static void input_tab(int *lastWasTab) | |||
764 | #if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION | 753 | #if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION |
765 | /* If the word starts with `~' and there is no slash in the word, | 754 | /* If the word starts with `~' and there is no slash in the word, |
766 | * then try completing this word as a username. */ | 755 | * then try completing this word as a username. */ |
767 | 756 | if (state->flags & USERNAME_COMPLETION) | |
768 | if (matchBuf[0] == '~' && strchr(matchBuf, '/') == 0) | 757 | if (matchBuf[0] == '~' && strchr(matchBuf, '/') == 0) |
769 | username_tab_completion(matchBuf, NULL); | 758 | username_tab_completion(matchBuf, NULL); |
770 | if (!matches) | ||
771 | #endif | 759 | #endif |
772 | /* Try to match any executable in our path and everything | 760 | /* Try to match any executable in our path and everything |
773 | * in the current working directory */ | 761 | * in the current working directory */ |
762 | if (!matches) | ||
774 | exe_n_cwd_tab_completion(matchBuf, find_type); | 763 | exe_n_cwd_tab_completion(matchBuf, find_type); |
775 | /* Sort, then remove any duplicates found */ | 764 | /* Sort, then remove any duplicates found */ |
776 | if (matches) { | 765 | if (matches) { |
@@ -855,51 +844,48 @@ static void input_tab(int *lastWasTab) | |||
855 | } | 844 | } |
856 | } | 845 | } |
857 | 846 | ||
847 | #else | ||
848 | #define input_tab(a) ((void)0) | ||
858 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ | 849 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ |
859 | 850 | ||
860 | 851 | ||
861 | #if MAX_HISTORY > 0 | 852 | #if MAX_HISTORY > 0 |
862 | 853 | ||
863 | static char *history[MAX_HISTORY+1]; /* history + current */ | 854 | /* state->flags is already checked to be nonzero */ |
864 | /* saved history lines */ | ||
865 | static int n_history; | ||
866 | /* current pointer to history line */ | ||
867 | static int cur_history; | ||
868 | |||
869 | static void get_previous_history(void) | 855 | static void get_previous_history(void) |
870 | { | 856 | { |
871 | if (command_ps[0] != '\0' || history[cur_history] == NULL) { | 857 | if (command_ps[0] != '\0' || state->history[state->cur_history] == NULL) { |
872 | free(history[cur_history]); | 858 | free(state->history[state->cur_history]); |
873 | history[cur_history] = xstrdup(command_ps); | 859 | state->history[state->cur_history] = xstrdup(command_ps); |
874 | } | 860 | } |
875 | cur_history--; | 861 | state->cur_history--; |
876 | } | 862 | } |
877 | 863 | ||
878 | static int get_next_history(void) | 864 | static int get_next_history(void) |
879 | { | 865 | { |
880 | int ch = cur_history; | 866 | if (state->flags & DO_HISTORY) { |
881 | 867 | int ch = state->cur_history; | |
882 | if (ch < n_history) { | 868 | if (ch < state->cnt_history) { |
883 | get_previous_history(); /* save the current history line */ | 869 | get_previous_history(); /* save the current history line */ |
884 | cur_history = ch + 1; | 870 | state->cur_history = ch + 1; |
885 | return cur_history; | 871 | return state->cur_history; |
886 | } else { | 872 | } |
887 | beep(); | ||
888 | return 0; | ||
889 | } | 873 | } |
874 | beep(); | ||
875 | return 0; | ||
890 | } | 876 | } |
891 | 877 | ||
892 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY | 878 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY |
879 | /* state->flags is already checked to be nonzero */ | ||
893 | void load_history(const char *fromfile) | 880 | void load_history(const char *fromfile) |
894 | { | 881 | { |
895 | FILE *fp; | 882 | FILE *fp; |
896 | int hi; | 883 | int hi; |
897 | 884 | ||
898 | /* cleanup old */ | 885 | /* cleanup old */ |
899 | 886 | for (hi = state->cnt_history; hi > 0;) { | |
900 | for (hi = n_history; hi > 0;) { | ||
901 | hi--; | 887 | hi--; |
902 | free(history[hi]); | 888 | free(state->history[hi]); |
903 | } | 889 | } |
904 | 890 | ||
905 | fp = fopen(fromfile, "r"); | 891 | fp = fopen(fromfile, "r"); |
@@ -917,29 +903,62 @@ void load_history(const char *fromfile) | |||
917 | free(hl); | 903 | free(hl); |
918 | continue; | 904 | continue; |
919 | } | 905 | } |
920 | history[hi++] = hl; | 906 | state->history[hi++] = hl; |
921 | } | 907 | } |
922 | fclose(fp); | 908 | fclose(fp); |
923 | } | 909 | } |
924 | cur_history = n_history = hi; | 910 | state->cur_history = state->cnt_history = hi; |
925 | } | 911 | } |
926 | 912 | ||
913 | /* state->flags is already checked to be nonzero */ | ||
927 | void save_history(const char *tofile) | 914 | void save_history(const char *tofile) |
928 | { | 915 | { |
929 | FILE *fp = fopen(tofile, "w"); | 916 | FILE *fp; |
930 | 917 | ||
918 | fp = fopen(tofile, "w"); | ||
931 | if (fp) { | 919 | if (fp) { |
932 | int i; | 920 | int i; |
933 | 921 | ||
934 | for (i = 0; i < n_history; i++) { | 922 | for (i = 0; i < state->cnt_history; i++) { |
935 | fprintf(fp, "%s\n", history[i]); | 923 | fprintf(fp, "%s\n", state->history[i]); |
936 | } | 924 | } |
937 | fclose(fp); | 925 | fclose(fp); |
938 | } | 926 | } |
939 | } | 927 | } |
928 | #else | ||
929 | #define load_history(a) ((void)0) | ||
930 | #define save_history(a) ((void)0) | ||
940 | #endif /* FEATURE_COMMAND_SAVEHISTORY */ | 931 | #endif /* FEATURE_COMMAND_SAVEHISTORY */ |
941 | 932 | ||
942 | #endif /* MAX_HISTORY > 0 */ | 933 | static void remember_in_history(const char *str) |
934 | { | ||
935 | int i; | ||
936 | |||
937 | if (!(state->flags & DO_HISTORY)) | ||
938 | return; | ||
939 | |||
940 | i = state->cnt_history; | ||
941 | free(state->history[MAX_HISTORY]); | ||
942 | state->history[MAX_HISTORY] = NULL; | ||
943 | /* After max history, remove the oldest command */ | ||
944 | if (i >= MAX_HISTORY) { | ||
945 | free(state->history[0]); | ||
946 | for (i = 0; i < MAX_HISTORY-1; i++) | ||
947 | state->history[i] = state->history[i+1]; | ||
948 | } | ||
949 | // Maybe "if (!i || strcmp(history[i-1], command) != 0) ..." | ||
950 | // (i.e. do not save dups?) | ||
951 | state->history[i++] = xstrdup(str); | ||
952 | state->cur_history = i; | ||
953 | state->cnt_history = i; | ||
954 | if (state->flags & SAVE_HISTORY) | ||
955 | save_history(state->hist_file); | ||
956 | USE_FEATURE_SH_FANCY_PROMPT(num_ok_lines++;) | ||
957 | } | ||
958 | |||
959 | #else /* MAX_HISTORY == 0 */ | ||
960 | #define remember_in_history(a) ((void)0) | ||
961 | #endif /* MAX_HISTORY */ | ||
943 | 962 | ||
944 | 963 | ||
945 | /* | 964 | /* |
@@ -960,13 +979,6 @@ void save_history(const char *tofile) | |||
960 | */ | 979 | */ |
961 | 980 | ||
962 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | 981 | #if ENABLE_FEATURE_COMMAND_EDITING_VI |
963 | static int vi_mode; | ||
964 | |||
965 | void setvimode(int viflag) | ||
966 | { | ||
967 | vi_mode = viflag; | ||
968 | } | ||
969 | |||
970 | static void | 982 | static void |
971 | vi_Word_motion(char *command, int eat) | 983 | vi_Word_motion(char *command, int eat) |
972 | { | 984 | { |
@@ -1058,13 +1070,11 @@ vi_back_motion(char *command) | |||
1058 | input_backward(1); | 1070 | input_backward(1); |
1059 | } | 1071 | } |
1060 | } | 1072 | } |
1061 | #else | ||
1062 | enum { vi_mode = 0 }; | ||
1063 | #endif | 1073 | #endif |
1064 | 1074 | ||
1065 | 1075 | ||
1066 | /* | 1076 | /* |
1067 | * cmdedit_read_input and its helpers | 1077 | * read_line_input and its helpers |
1068 | */ | 1078 | */ |
1069 | 1079 | ||
1070 | #if !ENABLE_FEATURE_SH_FANCY_PROMPT | 1080 | #if !ENABLE_FEATURE_SH_FANCY_PROMPT |
@@ -1190,7 +1200,7 @@ static void parse_prompt(const char *prmt_ptr) | |||
1190 | cmdedit_prmt_len += cur_prmt_len; | 1200 | cmdedit_prmt_len += cur_prmt_len; |
1191 | prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); | 1201 | prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); |
1192 | } | 1202 | } |
1193 | if (pwd_buf!=(char *)bb_msg_unknown) | 1203 | if (pwd_buf != (char *)bb_msg_unknown) |
1194 | free(pwd_buf); | 1204 | free(pwd_buf); |
1195 | cmdedit_prompt = prmt_mem_ptr; | 1205 | cmdedit_prompt = prmt_mem_ptr; |
1196 | put_prompt(); | 1206 | put_prompt(); |
@@ -1217,7 +1227,7 @@ static void cmdedit_setwidth(unsigned w, int redraw_flg) | |||
1217 | /* new y for current cursor */ | 1227 | /* new y for current cursor */ |
1218 | int new_y = (cursor + cmdedit_prmt_len) / w; | 1228 | int new_y = (cursor + cmdedit_prmt_len) / w; |
1219 | /* redraw */ | 1229 | /* redraw */ |
1220 | redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor); | 1230 | redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), command_len - cursor); |
1221 | fflush(stdout); | 1231 | fflush(stdout); |
1222 | } | 1232 | } |
1223 | } | 1233 | } |
@@ -1275,9 +1285,10 @@ static void cmdedit_init(void) | |||
1275 | #undef CTRL | 1285 | #undef CTRL |
1276 | #define CTRL(a) ((a) & ~0x40) | 1286 | #define CTRL(a) ((a) & ~0x40) |
1277 | 1287 | ||
1278 | 1288 | int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *st) | |
1279 | int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | ||
1280 | { | 1289 | { |
1290 | static const int null_flags; | ||
1291 | |||
1281 | int lastWasTab = FALSE; | 1292 | int lastWasTab = FALSE; |
1282 | unsigned int ic; | 1293 | unsigned int ic; |
1283 | unsigned char c; | 1294 | unsigned char c; |
@@ -1286,18 +1297,28 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1286 | smallint vi_cmdmode = 0; | 1297 | smallint vi_cmdmode = 0; |
1287 | smalluint prevc; | 1298 | smalluint prevc; |
1288 | #endif | 1299 | #endif |
1300 | |||
1301 | // FIXME: audit & improve this | ||
1302 | if (maxsize > BUFSIZ) | ||
1303 | maxsize = BUFSIZ; | ||
1304 | |||
1305 | /* With null flags, no other fields are ever used */ | ||
1306 | state = st ? st : (line_input_t*) &null_flags; | ||
1307 | if (state->flags & SAVE_HISTORY) | ||
1308 | load_history(state->hist_file); | ||
1309 | |||
1289 | /* prepare before init handlers */ | 1310 | /* prepare before init handlers */ |
1290 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ | 1311 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ |
1291 | len = 0; | 1312 | command_len = 0; |
1292 | command_ps = command; | 1313 | command_ps = command; |
1293 | command[0] = '\0'; | 1314 | command[0] = '\0'; |
1294 | 1315 | ||
1295 | getTermSettings(0, (void *) &initial_settings); | 1316 | getTermSettings(0, (void *) &initial_settings); |
1296 | memcpy(&new_settings, &initial_settings, sizeof(struct termios)); | 1317 | memcpy(&new_settings, &initial_settings, sizeof(new_settings)); |
1297 | new_settings.c_lflag &= ~ICANON; /* unbuffered input */ | 1318 | new_settings.c_lflag &= ~ICANON; /* unbuffered input */ |
1298 | /* Turn off echoing and CTRL-C, so we can trap it */ | 1319 | /* Turn off echoing and CTRL-C, so we can trap it */ |
1299 | new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); | 1320 | new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); |
1300 | /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ | 1321 | /* Hmm, in linux c_cc[] is not parsed if ICANON is off */ |
1301 | new_settings.c_cc[VMIN] = 1; | 1322 | new_settings.c_cc[VMIN] = 1; |
1302 | new_settings.c_cc[VTIME] = 0; | 1323 | new_settings.c_cc[VTIME] = 0; |
1303 | /* Turn off CTRL-C, so we can trap it */ | 1324 | /* Turn off CTRL-C, so we can trap it */ |
@@ -1354,34 +1375,18 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1354 | vi_case(CTRL('C')|vbit:) | 1375 | vi_case(CTRL('C')|vbit:) |
1355 | /* Control-c -- stop gathering input */ | 1376 | /* Control-c -- stop gathering input */ |
1356 | goto_new_line(); | 1377 | goto_new_line(); |
1357 | #if !ENABLE_ASH | 1378 | command_len = 0; |
1358 | command[0] = '\0'; | 1379 | break_out = -1; /* "do not append '\n'" */ |
1359 | len = 0; | ||
1360 | lastWasTab = FALSE; | ||
1361 | put_prompt(); | ||
1362 | #else | ||
1363 | len = 0; | ||
1364 | break_out = -1; /* to control traps */ | ||
1365 | #endif | ||
1366 | break; | 1380 | break; |
1367 | case CTRL('D'): | 1381 | case CTRL('D'): |
1368 | /* Control-d -- Delete one character, or exit | 1382 | /* Control-d -- Delete one character, or exit |
1369 | * if the len=0 and no chars to delete */ | 1383 | * if the len=0 and no chars to delete */ |
1370 | if (len == 0) { | 1384 | if (command_len == 0) { |
1371 | errno = 0; | 1385 | errno = 0; |
1372 | prepare_to_die: | 1386 | prepare_to_die: |
1373 | // So, our API depends on whether we have ash compiled in or not? Crap... | ||
1374 | #if !ENABLE_ASH | ||
1375 | printf("exit"); | ||
1376 | goto_new_line(); | ||
1377 | /* cmdedit_reset_term() called in atexit */ | ||
1378 | // FIXME. this is definitely not good | ||
1379 | exit(EXIT_SUCCESS); | ||
1380 | #else | ||
1381 | /* to control stopped jobs */ | 1387 | /* to control stopped jobs */ |
1382 | break_out = len = -1; | 1388 | break_out = command_len = -1; |
1383 | break; | 1389 | break; |
1384 | #endif | ||
1385 | } | 1390 | } |
1386 | input_delete(0); | 1391 | input_delete(0); |
1387 | break; | 1392 | break; |
@@ -1407,23 +1412,21 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1407 | break; | 1412 | break; |
1408 | 1413 | ||
1409 | case '\t': | 1414 | case '\t': |
1410 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION | ||
1411 | input_tab(&lastWasTab); | 1415 | input_tab(&lastWasTab); |
1412 | #endif | ||
1413 | break; | 1416 | break; |
1414 | 1417 | ||
1415 | #if ENABLE_FEATURE_EDITING_FANCY_KEYS | 1418 | #if ENABLE_FEATURE_EDITING_FANCY_KEYS |
1416 | case CTRL('K'): | 1419 | case CTRL('K'): |
1417 | /* Control-k -- clear to end of line */ | 1420 | /* Control-k -- clear to end of line */ |
1418 | command[cursor] = 0; | 1421 | command[cursor] = 0; |
1419 | len = cursor; | 1422 | command_len = cursor; |
1420 | printf("\033[J"); | 1423 | printf("\033[J"); |
1421 | break; | 1424 | break; |
1422 | case CTRL('L'): | 1425 | case CTRL('L'): |
1423 | vi_case(CTRL('L')|vbit:) | 1426 | vi_case(CTRL('L')|vbit:) |
1424 | /* Control-l -- clear screen */ | 1427 | /* Control-l -- clear screen */ |
1425 | printf("\033[H"); | 1428 | printf("\033[H"); |
1426 | redraw(0, len - cursor); | 1429 | redraw(0, command_len - cursor); |
1427 | break; | 1430 | break; |
1428 | #endif | 1431 | #endif |
1429 | 1432 | ||
@@ -1439,12 +1442,11 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1439 | vi_case(CTRL('P')|vbit:) | 1442 | vi_case(CTRL('P')|vbit:) |
1440 | vi_case('k'|vbit:) | 1443 | vi_case('k'|vbit:) |
1441 | /* Control-p -- Get previous command from history */ | 1444 | /* Control-p -- Get previous command from history */ |
1442 | if (cur_history > 0) { | 1445 | if ((state->flags & DO_HISTORY) && state->cur_history > 0) { |
1443 | get_previous_history(); | 1446 | get_previous_history(); |
1444 | goto rewrite_line; | 1447 | goto rewrite_line; |
1445 | } else { | ||
1446 | beep(); | ||
1447 | } | 1448 | } |
1449 | beep(); | ||
1448 | break; | 1450 | break; |
1449 | #endif | 1451 | #endif |
1450 | 1452 | ||
@@ -1454,7 +1456,8 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1454 | /* Control-U -- Clear line before cursor */ | 1456 | /* Control-U -- Clear line before cursor */ |
1455 | if (cursor) { | 1457 | if (cursor) { |
1456 | strcpy(command, command + cursor); | 1458 | strcpy(command, command + cursor); |
1457 | redraw(cmdedit_y, len -= cursor); | 1459 | command_len -= cursor; |
1460 | redraw(cmdedit_y, command_len); | ||
1458 | } | 1461 | } |
1459 | break; | 1462 | break; |
1460 | #endif | 1463 | #endif |
@@ -1571,7 +1574,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1571 | break; | 1574 | break; |
1572 | case '$': /* "d$", "c$" */ | 1575 | case '$': /* "d$", "c$" */ |
1573 | clear_to_eol: | 1576 | clear_to_eol: |
1574 | while (cursor < len) | 1577 | while (cursor < command_len) |
1575 | input_delete(1); | 1578 | input_delete(1); |
1576 | break; | 1579 | break; |
1577 | } | 1580 | } |
@@ -1599,7 +1602,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1599 | case '\x1b': /* ESC */ | 1602 | case '\x1b': /* ESC */ |
1600 | 1603 | ||
1601 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | 1604 | #if ENABLE_FEATURE_COMMAND_EDITING_VI |
1602 | if (vi_mode) { | 1605 | if (state->flags & VI_MODE) { |
1603 | /* ESC: insert mode --> command mode */ | 1606 | /* ESC: insert mode --> command mode */ |
1604 | vi_cmdmode = 1; | 1607 | vi_cmdmode = 1; |
1605 | input_backward(1); | 1608 | input_backward(1); |
@@ -1634,7 +1637,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1634 | #if MAX_HISTORY > 0 | 1637 | #if MAX_HISTORY > 0 |
1635 | case 'A': | 1638 | case 'A': |
1636 | /* Up Arrow -- Get previous command from history */ | 1639 | /* Up Arrow -- Get previous command from history */ |
1637 | if (cur_history > 0) { | 1640 | if ((state->flags & DO_HISTORY) && state->cur_history > 0) { |
1638 | get_previous_history(); | 1641 | get_previous_history(); |
1639 | goto rewrite_line; | 1642 | goto rewrite_line; |
1640 | } | 1643 | } |
@@ -1647,9 +1650,9 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1647 | rewrite_line: | 1650 | rewrite_line: |
1648 | /* Rewrite the line with the selected history item */ | 1651 | /* Rewrite the line with the selected history item */ |
1649 | /* change command */ | 1652 | /* change command */ |
1650 | len = strlen(strcpy(command, history[cur_history])); | 1653 | command_len = strlen(strcpy(command, state->history[state->cur_history])); |
1651 | /* redraw and go to eol (bol, in vi */ | 1654 | /* redraw and go to eol (bol, in vi */ |
1652 | redraw(cmdedit_y, vi_mode ? 9999 : 0); | 1655 | redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); |
1653 | break; | 1656 | break; |
1654 | #endif | 1657 | #endif |
1655 | case 'C': | 1658 | case 'C': |
@@ -1700,18 +1703,18 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1700 | if (!Isprint(c)) /* Skip non-printable characters */ | 1703 | if (!Isprint(c)) /* Skip non-printable characters */ |
1701 | break; | 1704 | break; |
1702 | 1705 | ||
1703 | if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */ | 1706 | if (command_len >= (maxsize - 2)) /* Need to leave space for enter */ |
1704 | break; | 1707 | break; |
1705 | 1708 | ||
1706 | len++; | 1709 | command_len++; |
1707 | if (cursor == (len - 1)) { /* Append if at the end of the line */ | 1710 | if (cursor == (command_len - 1)) { /* Append if at the end of the line */ |
1708 | command[cursor] = c; | 1711 | command[cursor] = c; |
1709 | command[cursor+1] = '\0'; | 1712 | command[cursor+1] = '\0'; |
1710 | cmdedit_set_out_char(' '); | 1713 | cmdedit_set_out_char(' '); |
1711 | } else { /* Insert otherwise */ | 1714 | } else { /* Insert otherwise */ |
1712 | int sc = cursor; | 1715 | int sc = cursor; |
1713 | 1716 | ||
1714 | memmove(command + sc + 1, command + sc, len - sc); | 1717 | memmove(command + sc + 1, command + sc, command_len - sc); |
1715 | command[sc] = c; | 1718 | command[sc] = c; |
1716 | sc++; | 1719 | sc++; |
1717 | /* rewrite from cursor */ | 1720 | /* rewrite from cursor */ |
@@ -1728,35 +1731,12 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1728 | lastWasTab = FALSE; | 1731 | lastWasTab = FALSE; |
1729 | } | 1732 | } |
1730 | 1733 | ||
1731 | #if MAX_HISTORY > 0 | 1734 | if (command_len > 0) |
1732 | /* Handle command history log */ | 1735 | remember_in_history(command); |
1733 | /* cleanup may be saved current command line */ | ||
1734 | if (len > 0) { | ||
1735 | int i = n_history; | ||
1736 | |||
1737 | free(history[MAX_HISTORY]); | ||
1738 | history[MAX_HISTORY] = NULL; | ||
1739 | /* After max history, remove the oldest command */ | ||
1740 | if (i >= MAX_HISTORY) { | ||
1741 | free(history[0]); | ||
1742 | for (i = 0; i < MAX_HISTORY-1; i++) | ||
1743 | history[i] = history[i+1]; | ||
1744 | } | ||
1745 | // Maybe "if (!i || strcmp(history[i-1], command) != 0) ..." | ||
1746 | // (i.e. do not save dups?) | ||
1747 | history[i++] = xstrdup(command); | ||
1748 | cur_history = i; | ||
1749 | n_history = i; | ||
1750 | USE_FEATURE_SH_FANCY_PROMPT(num_ok_lines++;) | ||
1751 | } | ||
1752 | #else /* MAX_HISTORY == 0 */ | ||
1753 | /* dont put empty line */ | ||
1754 | USE_FEATURE_SH_FANCY_PROMPT(if (len > 0) num_ok_lines++;) | ||
1755 | #endif /* MAX_HISTORY */ | ||
1756 | 1736 | ||
1757 | if (break_out > 0) { | 1737 | if (break_out > 0) { |
1758 | command[len++] = '\n'; | 1738 | command[command_len++] = '\n'; |
1759 | command[len] = '\0'; | 1739 | command[command_len] = '\0'; |
1760 | } | 1740 | } |
1761 | 1741 | ||
1762 | #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION | 1742 | #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION |
@@ -1764,11 +1744,29 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1764 | #endif | 1744 | #endif |
1765 | 1745 | ||
1766 | #if ENABLE_FEATURE_SH_FANCY_PROMPT | 1746 | #if ENABLE_FEATURE_SH_FANCY_PROMPT |
1767 | free(cmdedit_prompt); | 1747 | free((char*)cmdedit_prompt); |
1768 | #endif | 1748 | #endif |
1769 | /* restore initial_settings and SIGWINCH handler */ | 1749 | /* restore initial_settings and SIGWINCH handler */ |
1770 | cmdedit_reset_term(); | 1750 | cmdedit_reset_term(); |
1771 | return len; | 1751 | return command_len; |
1752 | } | ||
1753 | |||
1754 | line_input_t *new_line_input_t(int flags) | ||
1755 | { | ||
1756 | line_input_t *n = xzalloc(sizeof(*n)); | ||
1757 | n->flags = flags; | ||
1758 | return n; | ||
1759 | } | ||
1760 | |||
1761 | #else | ||
1762 | |||
1763 | #undef read_line_input | ||
1764 | int read_line_input(const char* prompt, char* command, int maxsize) | ||
1765 | { | ||
1766 | fputs(prompt, stdout); | ||
1767 | fflush(stdout); | ||
1768 | fgets(command, maxsize, stdin); | ||
1769 | return strlen(command); | ||
1772 | } | 1770 | } |
1773 | 1771 | ||
1774 | #endif /* FEATURE_COMMAND_EDITING */ | 1772 | #endif /* FEATURE_COMMAND_EDITING */ |
@@ -1801,13 +1799,13 @@ int main(int argc, char **argv) | |||
1801 | #endif | 1799 | #endif |
1802 | while (1) { | 1800 | while (1) { |
1803 | int l; | 1801 | int l; |
1804 | l = cmdedit_read_input(prompt, buff); | 1802 | l = read_line_input(prompt, buff); |
1805 | if (l <= 0 || buff[l-1] != '\n') | 1803 | if (l <= 0 || buff[l-1] != '\n') |
1806 | break; | 1804 | break; |
1807 | buff[l-1] = 0; | 1805 | buff[l-1] = 0; |
1808 | printf("*** cmdedit_read_input() returned line =%s=\n", buff); | 1806 | printf("*** read_line_input() returned line =%s=\n", buff); |
1809 | } | 1807 | } |
1810 | printf("*** cmdedit_read_input() detect ^D\n"); | 1808 | printf("*** read_line_input() detect ^D\n"); |
1811 | return 0; | 1809 | return 0; |
1812 | } | 1810 | } |
1813 | 1811 | ||
diff --git a/shell/cmdedit.h b/shell/cmdedit.h index 4a32cf63e..7af2f75fb 100644 --- a/shell/cmdedit.h +++ b/shell/cmdedit.h | |||
@@ -1,20 +1 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | /* TO DELETE */ | |
2 | #ifndef CMDEDIT_H | ||
3 | #define CMDEDIT_H | ||
4 | |||
5 | int cmdedit_read_input(char* promptStr, char* command); | ||
6 | |||
7 | #if ENABLE_ASH | ||
8 | extern const char *cmdedit_path_lookup; | ||
9 | #endif | ||
10 | |||
11 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY | ||
12 | void load_history(const char *fromfile); | ||
13 | void save_history(const char *tofile); | ||
14 | #endif | ||
15 | |||
16 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | ||
17 | void setvimode(int viflag); | ||
18 | #endif | ||
19 | |||
20 | #endif /* CMDEDIT_H */ | ||
diff --git a/shell/hush.c b/shell/hush.c index 8f2dc80f2..2c88238ae 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -98,7 +98,6 @@ | |||
98 | /* #include <dmalloc.h> */ | 98 | /* #include <dmalloc.h> */ |
99 | /* #define DEBUG_SHELL */ | 99 | /* #define DEBUG_SHELL */ |
100 | 100 | ||
101 | #include "cmdedit.h" | ||
102 | 101 | ||
103 | #define SPECIAL_VAR_SYMBOL 03 | 102 | #define SPECIAL_VAR_SYMBOL 03 |
104 | #define FLAG_EXIT_FROM_LOOP 1 | 103 | #define FLAG_EXIT_FROM_LOOP 1 |
@@ -883,20 +882,24 @@ static void setup_prompt_string(int promptmode, char **prompt_str) | |||
883 | debug_printf("result %s\n",*prompt_str); | 882 | debug_printf("result %s\n",*prompt_str); |
884 | } | 883 | } |
885 | 884 | ||
885 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
886 | static line_input_t *line_input_state; | ||
887 | #endif | ||
888 | |||
886 | static void get_user_input(struct in_str *i) | 889 | static void get_user_input(struct in_str *i) |
887 | { | 890 | { |
888 | char *prompt_str; | 891 | char *prompt_str; |
889 | static char the_command[BUFSIZ]; | 892 | static char the_command[BUFSIZ]; |
890 | 893 | ||
891 | setup_prompt_string(i->promptmode, &prompt_str); | 894 | setup_prompt_string(i->promptmode, &prompt_str); |
892 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 895 | #if ENABLE_FEATURE_COMMAND_EDITING |
893 | /* | 896 | /* |
894 | ** enable command line editing only while a command line | 897 | ** enable command line editing only while a command line |
895 | ** is actually being read; otherwise, we'll end up bequeathing | 898 | ** is actually being read; otherwise, we'll end up bequeathing |
896 | ** atexit() handlers and other unwanted stuff to our | 899 | ** atexit() handlers and other unwanted stuff to our |
897 | ** child processes (rob@sysgo.de) | 900 | ** child processes (rob@sysgo.de) |
898 | */ | 901 | */ |
899 | cmdedit_read_input(prompt_str, the_command); | 902 | read_line_input(prompt_str, the_command, BUFSIZ, line_input_state); |
900 | #else | 903 | #else |
901 | fputs(prompt_str, stdout); | 904 | fputs(prompt_str, stdout); |
902 | fflush(stdout); | 905 | fflush(stdout); |
@@ -2647,6 +2650,10 @@ int hush_main(int argc, char **argv) | |||
2647 | FILE *input; | 2650 | FILE *input; |
2648 | char **e = environ; | 2651 | char **e = environ; |
2649 | 2652 | ||
2653 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | ||
2654 | line_input_state = new_line_input_t(FOR_SHELL); | ||
2655 | #endif | ||
2656 | |||
2650 | /* XXX what should these be while sourcing /etc/profile? */ | 2657 | /* XXX what should these be while sourcing /etc/profile? */ |
2651 | global_argc = argc; | 2658 | global_argc = argc; |
2652 | global_argv = argv; | 2659 | global_argv = argv; |
diff --git a/shell/lash.c b/shell/lash.c index b2ccaf0a1..a09a9a9b1 100644 --- a/shell/lash.c +++ b/shell/lash.c | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | #include "busybox.h" | 24 | #include "busybox.h" |
25 | #include <getopt.h> | 25 | #include <getopt.h> |
26 | #include "cmdedit.h" | ||
27 | |||
28 | #include <glob.h> | 26 | #include <glob.h> |
29 | #define expand_t glob_t | 27 | #define expand_t glob_t |
30 | 28 | ||
@@ -641,6 +639,10 @@ static inline void setup_prompt_string(char **prompt_str) | |||
641 | #endif | 639 | #endif |
642 | } | 640 | } |
643 | 641 | ||
642 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
643 | static line_input_t *line_input_state; | ||
644 | #endif | ||
645 | |||
644 | static int get_command(FILE * source, char *command) | 646 | static int get_command(FILE * source, char *command) |
645 | { | 647 | { |
646 | char *prompt_str; | 648 | char *prompt_str; |
@@ -659,14 +661,14 @@ static int get_command(FILE * source, char *command) | |||
659 | if (source == stdin) { | 661 | if (source == stdin) { |
660 | setup_prompt_string(&prompt_str); | 662 | setup_prompt_string(&prompt_str); |
661 | 663 | ||
662 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 664 | #if ENABLE_FEATURE_COMMAND_EDITING |
663 | /* | 665 | /* |
664 | ** enable command line editing only while a command line | 666 | ** enable command line editing only while a command line |
665 | ** is actually being read; otherwise, we'll end up bequeathing | 667 | ** is actually being read; otherwise, we'll end up bequeathing |
666 | ** atexit() handlers and other unwanted stuff to our | 668 | ** atexit() handlers and other unwanted stuff to our |
667 | ** child processes (rob@sysgo.de) | 669 | ** child processes (rob@sysgo.de) |
668 | */ | 670 | */ |
669 | cmdedit_read_input(prompt_str, command); | 671 | read_line_input(prompt_str, command, BUFSIZ, line_input_state); |
670 | return 0; | 672 | return 0; |
671 | #else | 673 | #else |
672 | fputs(prompt_str, stdout); | 674 | fputs(prompt_str, stdout); |
@@ -1505,6 +1507,10 @@ int lash_main(int argc_l, char **argv_l) | |||
1505 | argc = argc_l; | 1507 | argc = argc_l; |
1506 | argv = argv_l; | 1508 | argv = argv_l; |
1507 | 1509 | ||
1510 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
1511 | line_input_state = new_line_input_t(FOR_SHELL); | ||
1512 | #endif | ||
1513 | |||
1508 | /* These variables need re-initializing when recursing */ | 1514 | /* These variables need re-initializing when recursing */ |
1509 | last_jobid = 0; | 1515 | last_jobid = 0; |
1510 | close_me_list = NULL; | 1516 | close_me_list = NULL; |
diff --git a/shell/msh.c b/shell/msh.c index c88308f8f..8746e42bc 100644 --- a/shell/msh.c +++ b/shell/msh.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <setjmp.h> | 17 | #include <setjmp.h> |
18 | #include <sys/times.h> | 18 | #include <sys/times.h> |
19 | 19 | ||
20 | #include "cmdedit.h" | ||
21 | 20 | ||
22 | /*#define MSHDEBUG 1*/ | 21 | /*#define MSHDEBUG 1*/ |
23 | 22 | ||
@@ -777,7 +776,7 @@ void print_tree(struct op *head) | |||
777 | #endif /* MSHDEBUG */ | 776 | #endif /* MSHDEBUG */ |
778 | 777 | ||
779 | 778 | ||
780 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 779 | #if ENABLE_FEATURE_COMMAND_EDITING |
781 | static char *current_prompt; | 780 | static char *current_prompt; |
782 | #endif | 781 | #endif |
783 | 782 | ||
@@ -787,6 +786,10 @@ static char *current_prompt; | |||
787 | */ | 786 | */ |
788 | 787 | ||
789 | 788 | ||
789 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
790 | static line_input_t *line_input_state; | ||
791 | #endif | ||
792 | |||
790 | int msh_main(int argc, char **argv) | 793 | int msh_main(int argc, char **argv) |
791 | { | 794 | { |
792 | int f; | 795 | int f; |
@@ -795,6 +798,10 @@ int msh_main(int argc, char **argv) | |||
795 | char *name, **ap; | 798 | char *name, **ap; |
796 | int (*iof) (struct ioarg *); | 799 | int (*iof) (struct ioarg *); |
797 | 800 | ||
801 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
802 | line_input_state = new_line_input_t(FOR_SHELL); | ||
803 | #endif | ||
804 | |||
798 | DBGPRINTF(("MSH_MAIN: argc %d, environ %p\n", argc, environ)); | 805 | DBGPRINTF(("MSH_MAIN: argc %d, environ %p\n", argc, environ)); |
799 | 806 | ||
800 | initarea(); | 807 | initarea(); |
@@ -964,7 +971,7 @@ int msh_main(int argc, char **argv) | |||
964 | 971 | ||
965 | for (;;) { | 972 | for (;;) { |
966 | if (interactive && e.iop <= iostack) { | 973 | if (interactive && e.iop <= iostack) { |
967 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 974 | #if ENABLE_FEATURE_COMMAND_EDITING |
968 | current_prompt = prompt->value; | 975 | current_prompt = prompt->value; |
969 | #else | 976 | #else |
970 | prs(prompt->value); | 977 | prs(prompt->value); |
@@ -2371,7 +2378,7 @@ static int yylex(int cf) | |||
2371 | startl = 1; | 2378 | startl = 1; |
2372 | if (multiline || cf & CONTIN) { | 2379 | if (multiline || cf & CONTIN) { |
2373 | if (interactive && e.iop <= iostack) { | 2380 | if (interactive && e.iop <= iostack) { |
2374 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 2381 | #if ENABLE_FEATURE_COMMAND_EDITING |
2375 | current_prompt = cprompt->value; | 2382 | current_prompt = cprompt->value; |
2376 | #else | 2383 | #else |
2377 | prs(cprompt->value); | 2384 | prs(cprompt->value); |
@@ -2432,7 +2439,7 @@ static int collect(int c, int c1) | |||
2432 | return YYERRCODE; | 2439 | return YYERRCODE; |
2433 | } | 2440 | } |
2434 | if (interactive && c == '\n' && e.iop <= iostack) { | 2441 | if (interactive && c == '\n' && e.iop <= iostack) { |
2435 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 2442 | #if ENABLE_FEATURE_COMMAND_EDITING |
2436 | current_prompt = cprompt->value; | 2443 | current_prompt = cprompt->value; |
2437 | #else | 2444 | #else |
2438 | prs(cprompt->value); | 2445 | prs(cprompt->value); |
@@ -4666,7 +4673,7 @@ static int readc(void) | |||
4666 | return e.iop->prev = 0; | 4673 | return e.iop->prev = 0; |
4667 | } | 4674 | } |
4668 | if (interactive && e.iop == iostack + 1) { | 4675 | if (interactive && e.iop == iostack + 1) { |
4669 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 4676 | #if ENABLE_FEATURE_COMMAND_EDITING |
4670 | current_prompt = prompt->value; | 4677 | current_prompt = prompt->value; |
4671 | #else | 4678 | #else |
4672 | prs(prompt->value); | 4679 | prs(prompt->value); |
@@ -4898,13 +4905,13 @@ static int filechar(struct ioarg *ap) | |||
4898 | ap->afpos++; | 4905 | ap->afpos++; |
4899 | return *bp->bufp++ & 0177; | 4906 | return *bp->bufp++ & 0177; |
4900 | } | 4907 | } |
4901 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 4908 | #if ENABLE_FEATURE_COMMAND_EDITING |
4902 | if (interactive && isatty(ap->afile)) { | 4909 | if (interactive && isatty(ap->afile)) { |
4903 | static char mycommand[BUFSIZ]; | 4910 | static char mycommand[BUFSIZ]; |
4904 | static int position = 0, size = 0; | 4911 | static int position = 0, size = 0; |
4905 | 4912 | ||
4906 | while (size == 0 || position >= size) { | 4913 | while (size == 0 || position >= size) { |
4907 | cmdedit_read_input(current_prompt, mycommand); | 4914 | read_line_input(current_prompt, mycommand, BUFSIZ, line_input_state); |
4908 | size = strlen(mycommand); | 4915 | size = strlen(mycommand); |
4909 | position = 0; | 4916 | position = 0; |
4910 | } | 4917 | } |
@@ -4913,7 +4920,6 @@ static int filechar(struct ioarg *ap) | |||
4913 | return c; | 4920 | return c; |
4914 | } else | 4921 | } else |
4915 | #endif | 4922 | #endif |
4916 | |||
4917 | { | 4923 | { |
4918 | i = safe_read(ap->afile, &c, sizeof(c)); | 4924 | i = safe_read(ap->afile, &c, sizeof(c)); |
4919 | return i == sizeof(c) ? (c & 0x7f) : (closef(ap->afile), 0); | 4925 | return i == sizeof(c) ? (c & 0x7f) : (closef(ap->afile), 0); |
@@ -5150,7 +5156,7 @@ static void readhere(char **name, char *s, int ec) | |||
5150 | e.iobase = e.iop; | 5156 | e.iobase = e.iop; |
5151 | for (;;) { | 5157 | for (;;) { |
5152 | if (interactive && e.iop <= iostack) { | 5158 | if (interactive && e.iop <= iostack) { |
5153 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 5159 | #if ENABLE_FEATURE_COMMAND_EDITING |
5154 | current_prompt = cprompt->value; | 5160 | current_prompt = cprompt->value; |
5155 | #else | 5161 | #else |
5156 | prs(cprompt->value); | 5162 | prs(cprompt->value); |