aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-22 07:21:38 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-22 07:21:38 +0000
commit8e1c71529c2bf38a04d4a117e625e59044a0785a (patch)
tree2f115293c25e7ee9307f268ec198e2cf486ff070 /shell/ash.c
parent00cdbd8fc20a4e2e2208f90a2691a3806c931b06 (diff)
downloadbusybox-w32-8e1c71529c2bf38a04d4a117e625e59044a0785a.tar.gz
busybox-w32-8e1c71529c2bf38a04d4a117e625e59044a0785a.tar.bz2
busybox-w32-8e1c71529c2bf38a04d4a117e625e59044a0785a.zip
Convert cmdedit into more generic line input facility
(make history and completion optional at runtime). Use it for fdisk, as an example. Some unrelated fixes in fdisk are also here.
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c106
1 files changed, 52 insertions, 54 deletions
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 **);
1238static int getoptscmd(int, char **); 1237static int getoptscmd(int, char **);
1239#endif 1238#endif
1240static int hashcmd(int, char **); 1239static int hashcmd(int, char **);
1241#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET 1240#if !ENABLE_FEATURE_SH_EXTRA_QUIET
1242static int helpcmd(int argc, char **argv); 1241static 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 6044static line_input_t *line_input_state;
6050#ifdef CONFIG_ASH_EXPAND_PRMT 6045//static SKIP_ASH_EXPAND_PRMT(const) char *cmdedit_prompt;
6051static char *cmdedit_prompt;
6052#else
6053static const char *cmdedit_prompt; 6046static const char *cmdedit_prompt;
6054#endif
6055static void putprompt(const char *s) 6047static 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
6065static void putprompt(const char *s) 6057static 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
6071static int preadfd(void) 6073static 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
6077retry: 6079retry:
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
8006state4: /* 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
11903static int helpcmd(int argc, char **argv) 11909static 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
11966out: 11964out:
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
13494static arith_t arith (const char *expr, int *perrcode) 13492static 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;