Several fixes.
authorErik Andersen <andersen@codepoet.org>
Fri, 17 Mar 2000 01:12:41 +0000 (01:12 -0000)
committerErik Andersen <andersen@codepoet.org>
Fri, 17 Mar 2000 01:12:41 +0000 (01:12 -0000)
 -Erik

15 files changed:
applets/busybox.c
applets/busybox.mkll
applets/busybox.sh
busybox.c
busybox.def.h
busybox.mkll
busybox.sh
cmdedit.c
kill.c
lash.c
procps/kill.c
sh.c
shell/cmdedit.c
shell/lash.c
utility.c

index 7582647d5b4f84c25d16070f365eff0657265559..ee745e73e1753e98f560f199241a507e31e07706 100644 (file)
@@ -4,10 +4,6 @@
 #include <string.h>
 #include <errno.h>
 
-#ifndef BB_INIT
-#undef BB_FEATURE_LINUXRC
-#endif
-
 static int been_there_done_that = 0;
 
 /* It has been alledged that doing such things can
index fa1bff209b11c9a27adb494fca3937c5d0e9569b..90f28e8b73352041d31643fa463d27855fccbc63 100755 (executable)
@@ -4,7 +4,8 @@
 DF="busybox.def.h"
 MF="busybox.c"
 
-LIST="$(sed -n '/^#define/{s/^#define BB_FEATURE_.*//g;s/^#define //p;}' $DF)"
+#LIST="$(sed -n '/^#define/{s/^#define BB_FEATURE_.*//g;s/^#define //p;}' $DF)"
+LIST="$(cpp $DF -dM | sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1/gp;' | sort)"
 
 for def in ${LIST}; do
        i=`sed -n '/^#ifdef \<'$def'\>.*/,/^#endif/{ s/.*\"\(.*\)\".*\(_BB_DIR_[A-Z_]*\).*$/\2\/\1/gp; }' $MF`
index 304ac87e7d0cc3024daf7b13fff717139c8b486f..c4e241f843a8b060d03d96f96668cb9d90c67ffa 100755 (executable)
@@ -1,3 +1,10 @@
 #!/bin/sh
-sed -n -e 's/^#define.*BB_FEATURE.*$//g;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;' \
-    -e '/^#define/{s/.*bb_//;s/$/.o/p;}' busybox.def.h
+
+# I added in the extra "ls" so only source files that
+# actually exist will show up in the compile list.
+ls -1 ` \
+    cpp busybox.def.h -dM | \
+    sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1.c/gp;' \
+    | tr [:upper:] [:lower:] | sort
+` 2>/dev/null | sed -e 's/\.c$/\.o/g'
+
index 7582647d5b4f84c25d16070f365eff0657265559..ee745e73e1753e98f560f199241a507e31e07706 100644 (file)
--- a/busybox.c
+++ b/busybox.c
@@ -4,10 +4,6 @@
 #include <string.h>
 #include <errno.h>
 
-#ifndef BB_INIT
-#undef BB_FEATURE_LINUXRC
-#endif
-
 static int been_there_done_that = 0;
 
 /* It has been alledged that doing such things can
index d78a0efe838d0c252591813ada17fb37974f136c..cfafc29c84575c0761443379650923d20f4a0928 100644 (file)
@@ -40,6 +40,7 @@
 // Don't bother turning BB_INSMOD on.  It doesn't work.
 //#define BB_INSMOD
 #define BB_KILL
+#define BB_KILLALL
 #define BB_KLOGD
 //#define BB_LENGTH
 #define BB_LN
 #define BB_MTAB
 #endif
 //
-#ifdef BB_FEATURE_FULL_REGULAR_EXPRESSIONS
+#if defined BB_FEATURE_FULL_REGULAR_EXPRESSIONS && (defined BB_SED || defined BB_GREP )
 #define BB_REGEXP
 #endif
 //
-#ifdef BB_FEATURE_SH_COMMAND_EDITING
+#if defined BB_FEATURE_SH_COMMAND_EDITING && defined BB_SH
 #define BB_CMDEDIT
 #endif
 //
+#ifdef BB_KILLALL
+#ifndef BB_KILL
+#define BB_KILL
+#endif
+#endif
+//
+#ifdef BB_FEATURE_LINUXRC
+#ifndef BB_INIT
+#define BB_INIT
+#endif
+#endif
+//
index fa1bff209b11c9a27adb494fca3937c5d0e9569b..90f28e8b73352041d31643fa463d27855fccbc63 100755 (executable)
@@ -4,7 +4,8 @@
 DF="busybox.def.h"
 MF="busybox.c"
 
-LIST="$(sed -n '/^#define/{s/^#define BB_FEATURE_.*//g;s/^#define //p;}' $DF)"
+#LIST="$(sed -n '/^#define/{s/^#define BB_FEATURE_.*//g;s/^#define //p;}' $DF)"
+LIST="$(cpp $DF -dM | sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1/gp;' | sort)"
 
 for def in ${LIST}; do
        i=`sed -n '/^#ifdef \<'$def'\>.*/,/^#endif/{ s/.*\"\(.*\)\".*\(_BB_DIR_[A-Z_]*\).*$/\2\/\1/gp; }' $MF`
index 304ac87e7d0cc3024daf7b13fff717139c8b486f..c4e241f843a8b060d03d96f96668cb9d90c67ffa 100755 (executable)
@@ -1,3 +1,10 @@
 #!/bin/sh
-sed -n -e 's/^#define.*BB_FEATURE.*$//g;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;' \
-    -e '/^#define/{s/.*bb_//;s/$/.o/p;}' busybox.def.h
+
+# I added in the extra "ls" so only source files that
+# actually exist will show up in the compile list.
+ls -1 ` \
+    cpp busybox.def.h -dM | \
+    sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1.c/gp;' \
+    | tr [:upper:] [:lower:] | sort
+` 2>/dev/null | sed -e 's/\.c$/\.o/g'
+
index d1604f1d1dc41423bcfe03bc1cfb90d135b44867..314e8cd661804940a03a4c15a61162911f7c57e6 100644 (file)
--- a/cmdedit.c
+++ b/cmdedit.c
@@ -47,6 +47,8 @@
 
 #define ESC    27
 #define DEL    127
+#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
 
 static struct history *his_front = NULL;       /* First element in command line list */
 static struct history *his_end = NULL; /* Last element in command line list */
@@ -104,7 +106,7 @@ void cmdedit_reset_term(void)
        xioctl(fileno(stdin), TCSETA, (void *) &old_term);
 }
 
-void gotaSignal(int sig)
+void prepareToDie(int sig)
 {
     cmdedit_reset_term();
     fprintf(stdout, "\n");
@@ -175,6 +177,40 @@ void input_backspace(int outputFd, int *cursor, int *len)
     }
 }
 
+char **username_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin username_completion_matches\n");
+    return ( (char**) NULL);
+}
+char **command_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin command_completion_matches\n");
+    return ( (char**) NULL);
+}
+char **directory_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin directory_completion_matches\n");
+    return ( (char**) NULL);
+}
+
+/*
+ * This function is used to grab a character buffer
+ * from the input file descriptor and allows you to
+ * a string with full command editing (sortof like
+ * a mini readline).
+ *
+ * The following standard commands are not implemented:
+ * ESC-b -- Move back one word
+ * ESC-f -- Move forward one word
+ * ESC-d -- Delete back one word
+ * ESC-h -- Delete forward one word
+ * CTL-t -- Transpose two characters
+ *
+ * Furthermore, the "vi" command editing keys are not implemented.
+ *
+ * TODO: implement TAB command completion. :)
+ *
+ */
 extern int cmdedit_read_input(int inputFd, int outputFd,
                            char command[BUFSIZ])
 {
@@ -185,6 +221,8 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
     int cursor = 0;
     int break_out = 0;
     int ret = 0;
+    int lastWasTab = FALSE;
+    char **matches = (char **)NULL;
     char c = 0;
     struct history *hp = his_end;
 
@@ -209,90 +247,233 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
 
        if ((ret = read(inputFd, &c, 1)) < 1)
            return ret;
-
+       
        switch (c) {
-       case 1:         /* Control-A Beginning of line */
+       case 1:         
+           /* Control-a -- Beginning of line */
            input_home(outputFd, &cursor);
-           break;
-       case 5:         /* Control-E EOL */
+       case 5:         
+           /* Control-e -- End of line */
            input_end(outputFd, &cursor, len);
            break;
-       case 4:         /* Control-D */
+       case 2:
+           /* Control-b -- Move back one character */
+           if (cursor > 0) {
+               xwrite(outputFd, "\033[D", 3);
+               cursor--;
+           }
+           break;
+       case 6: 
+           /* Control-f -- Move forward one character */
+           if (cursor < len) {
+               xwrite(outputFd, "\033[C", 3);
+               cursor++;
+           }
+           break;
+       case 4:
+           /* Control-d -- Delete one character */
            if (cursor != len) {
                input_delete(outputFd, cursor);
                len--;
+           } else if (len == 0) {
+               prepareToDie(0);
+               exit(0);
+           }
+           break;
+       case 14:
+           /* Control-n -- Get next command */
+           if (hp && hp->n && hp->n->s) {      
+               free( hp->s);
+               hp->s = strdup(parsenextc);
+               hp = hp->n;
+               goto hop;
            }
            break;
-       case '\b':              /* Backspace */
+       case 16:
+           /* Control-p -- Get previous command */
+           if (hp && hp->p) {  
+               free( hp->s);
+               hp->s = strdup(parsenextc);
+               hp = hp->p;
+               goto hop;
+           }
+           break;
+       case '\t':
+           {
+           /* Do TAB completion */
+               int in_command_position=0, ti=len-1;
+
+               if (lastWasTab == FALSE) {
+                   char *tmp;
+                   char *matchBuf;
+
+                   if (matches) {
+                       free(matches);
+                       matches = (char **)NULL;
+                   }
+
+                   matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
+
+                   /* Make a local copy of the string -- up 
+                    * to the the position of the cursor */
+                   strcpy( matchBuf, parsenextc); 
+                   matchBuf[cursor+1] = '\0';
+
+                   /* skip leading white space */
+                   tmp = matchBuf;
+                   while (*tmp && isspace(*tmp)) {
+                       (tmp)++;
+                       ti++;
+                   }
+
+                   /* Determine if this is a command word or not */
+                   //while ((ti > -1) && (whitespace (matchBuf[ti]))) {
+//printf("\nti=%d\n", ti);
+               //      ti--;
+                //   }
+printf("\nti=%d\n", ti);
+
+                   if (ti < 0) {
+                         in_command_position++;
+                   } else if (member(matchBuf[ti], ";|&{(`")) {
+                       int this_char, prev_char;
+                       in_command_position++;
+                       /* Handle the two character tokens `>&', `<&', and `>|'.
+                        We are not in a command position after one of these. */
+                       this_char = matchBuf[ti];
+                       prev_char = matchBuf[ti - 1];
+
+                       if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
+                               (this_char == '|' && prev_char == '>')) {
+                           in_command_position = 0;
+                       } 
+                       /* For now, do not bother with catching quoted
+                        * expressions and marking them as not in command
+                        * positions.  Some other day.  Or not.
+                        */
+                       //else if (char_is_quoted (matchBuf, ti)) {
+                       //    in_command_position = 0;
+                       //}
+                   }
+printf("\nin_command_position=%d\n", in_command_position);
+                   /* If the word starts in `~', and there is no slash in the word, 
+                    * then try completing this word as a username. */
+                   if (*matchBuf == '~' && !strchr (matchBuf, '/'))
+                       matches = username_completion_matches(matchBuf);
+
+                   /* If this word is in a command position, then complete over possible 
+                    * command names, including aliases, built-ins, and executables. */
+                   if (!matches && in_command_position) {
+                       matches = command_completion_matches(matchBuf);
+
+                   /* If we are attempting command completion and nothing matches, 
+                    * then try and match directories as a last resort... */
+                   if (!matches)
+                       matches = directory_completion_matches(matchBuf);
+                   }
+               } else {
+                   printf("\nprinting match list\n");
+               }
+               /* Rewrite the whole line (for debugging) */
+               for (; cursor > 0; cursor--)    
+                   xwrite(outputFd, "\b", 1);
+               len = strlen(parsenextc);
+               xwrite(outputFd, parsenextc, len);
+               cursor = len;
+               break;
+           }
+       case '\b':              
        case DEL:
+           /* Backspace */
            input_backspace(outputFd, &cursor, &len);
            break;
-       case '\n':              /* Enter */
+       case '\n':              
+           /* Enter */
            *(parsenextc + len++ + 1) = c;
            xwrite(outputFd, &c, 1);
            break_out = 1;
            break;
-       case ESC:               /* escape sequence follows */
+       case ESC:               {
+           /* escape sequence follows */
            if ((ret = read(inputFd, &c, 1)) < 1)
                return ret;
 
            if (c == '[') {     /* 91 */
                if ((ret = read(inputFd, &c, 1)) < 1)
                    return ret;
-
+               
                switch (c) {
                case 'A':
-                   if (hp && hp->p) {  /* Up */
+                   /* Up Arrow -- Get previous command */
+                   if (hp && hp->p) {  
+                       free( hp->s);
+                       hp->s = strdup(parsenextc);
                        hp = hp->p;
                        goto hop;
                    }
                    break;
                case 'B':
-                   if (hp && hp->n && hp->n->s) {      /* Down */
+                   /* Down Arrow -- Get next command */
+                   if (hp && hp->n && hp->n->s) {      
+                       free( hp->s);
+                       hp->s = strdup(parsenextc);
                        hp = hp->n;
                        goto hop;
                    }
                    break;
 
-                 hop:          /* hop */
+                   /* This is where we rewrite the line 
+                    * using the selected history item */
+                 hop:          
                    len = strlen(parsenextc);
 
-                   for (; cursor > 0; cursor--)        /* return to begining of line */
+                   /* return to begining of line */
+                   for (; cursor > 0; cursor--)        
                        xwrite(outputFd, "\b", 1);
+                   xwrite(outputFd, parsenextc, len);
 
-                   for (j = 0; j < len; j++)   /* erase old command */
+                   /* erase old command */
+                   for (j = 0; j < len; j++)   
                        xwrite(outputFd, " ", 1);
 
-                   for (j = len; j > 0; j--)   /* return to begining of line */
+                   /* return to begining of line */
+                   for (j = len; j > 0; j--)   
                        xwrite(outputFd, "\b", 1);
 
-                   strcpy(parsenextc, hp->s);  /* write new command */
+                   memset(parsenextc, 0, BUFSIZ);
+                   /* write new command */
+                   strcpy(parsenextc, hp->s);  
                    len = strlen(hp->s);
                    xwrite(outputFd, parsenextc, len);
                    cursor = len;
                    break;
-               case 'C':       /* Right */
+               case 'C':       
+                   /* Right Arrow -- Move forward one character */
                    if (cursor < len) {
                        xwrite(outputFd, "\033[C", 3);
                        cursor++;
                    }
                    break;
-               case 'D':       /* Left */
+               case 'D':       
+                   /* Left Arrow -- Move back one character */
                    if (cursor > 0) {
                        xwrite(outputFd, "\033[D", 3);
                        cursor--;
                    }
                    break;
-               case '3':       /* Delete */
+               case '3':       
+                   /* Delete */
                    if (cursor != len) {
                        input_delete(outputFd, cursor);
                        len--;
                    }
                    break;
-               case '1':       /* Home (Ctrl-A) */
+               case '1':       
+                   /* Home (Ctrl-A) */
                    input_home(outputFd, &cursor);
                    break;
-               case '4':       /* End (Ctrl-E) */
+               case '4':       
+                   /* End (Ctrl-E) */
                    input_end(outputFd, &cursor, len);
                    break;
                }
@@ -300,20 +481,24 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
                    if ((ret = read(inputFd, &c, 1)) < 1)
                        return ret;     /* read 126 (~) */
            }
-           if (c == 'O') {     /* 79 */
+           if (c == 'O') {     
+               /* 79 */
                if ((ret = read(inputFd, &c, 1)) < 1)
                    return ret;
                switch (c) {
-               case 'H':       /* Home (xterm) */
+               case 'H':       
+                   /* Home (xterm) */
                    input_home(outputFd, &cursor);
                    break;
-               case 'F':       /* End (xterm) */
+               case 'F':       
+                   /* End (xterm) */
                    input_end(outputFd, &cursor, len);
                    break;
                }
            }
            c = 0;
            break;
+       }
 
        default:                /* If it's regular input, do the normal thing */
 
@@ -343,6 +528,10 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
            xwrite(outputFd, &c, 1);
            break;
        }
+       if (c=='\t')
+           lastWasTab = TRUE;
+       else
+           lastWasTab = FALSE;
 
        if (break_out)          /* Enter is the command terminator, no more input. */
            break;
@@ -353,32 +542,33 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
     reset_term = 0;
 
 
-    if (*(parsenextc)) {       /* Handle command history log */
+    /* Handle command history log */
+    if (*(parsenextc)) {       
 
        struct history *h = his_end;
 
-       if (!h) {               /* No previous history */
+       if (!h) {               
+           /* No previous history */
            h = his_front = malloc(sizeof(struct history));
            h->n = malloc(sizeof(struct history));
            h->p = NULL;
            h->s = strdup(parsenextc);
-
            h->n->p = h;
            h->n->n = NULL;
            h->n->s = NULL;
            his_end = h->n;
            history_counter++;
-       } else {                /* Add a new history command */
-
+       } else {                
+           /* Add a new history command */
            h->n = malloc(sizeof(struct history));
-
            h->n->p = h;
            h->n->n = NULL;
            h->n->s = NULL;
            h->s = strdup(parsenextc);
            his_end = h->n;
 
-           if (history_counter >= MAX_HISTORY) {       /* After max history, remove the last known command */
+           /* After max history, remove the oldest command */
+           if (history_counter >= MAX_HISTORY) {       
 
                struct history *p = his_front->n;
 
@@ -398,8 +588,8 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
 extern void cmdedit_init(void)
 {
     atexit(cmdedit_reset_term);
-    signal(SIGINT, gotaSignal);
-    signal(SIGQUIT, gotaSignal);
-    signal(SIGTERM, gotaSignal);
+    signal(SIGINT, prepareToDie);
+    signal(SIGQUIT, prepareToDie);
+    signal(SIGTERM, prepareToDie);
 }
 #endif                         /* BB_FEATURE_SH_COMMAND_EDITING */
diff --git a/kill.c b/kill.c
index 8a99e0f9e99d016044a8c85974a91d3a787ee5e2..10343a150ad6bd170bf78e4f63c680544f9d0bb9 100644 (file)
--- a/kill.c
+++ b/kill.c
@@ -36,11 +36,12 @@ static const char *kill_usage =
        "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
        "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
 
+#ifdef BB_KILLALL
 static const char *killall_usage =
        "killall [-signal] process-name [process-name ...]\n\n"
        "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
        "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
-
+#endif
 
 #define KILL   0
 #define KILLALL        1
@@ -132,10 +133,15 @@ extern int kill_main(int argc, char **argv)
        int whichApp, sig = SIGTERM;
        const char *appUsage;
 
+#ifdef BB_KILLALL
        /* Figure out what we are trying to do here */
        whichApp = (strcmp(*argv, "killall") == 0)? 
                KILLALL : KILL; 
        appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
+#else
+       whichApp = KILL;
+       appUsage = kill_usage;
+#endif
 
        argc--;
        argv++;
@@ -213,7 +219,9 @@ extern int kill_main(int argc, char **argv)
                                fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
                        argv++;
                }
-       } else {
+       } 
+#ifdef BB_KILLALL
+       else {
                /* Looks like they want to do a killall.  Do that */
                while (--argc >= 0) {
                        int pid;
@@ -225,6 +233,7 @@ extern int kill_main(int argc, char **argv)
                        argv++;
                }
        }
+#endif
 
        exit(TRUE);
 
diff --git a/lash.c b/lash.c
index e143cfe740393c2ac1a51c127104b3559ef12873..068159697f7d028288ada542e36df83c689c14b3 100644 (file)
--- a/lash.c
+++ b/lash.c
@@ -98,7 +98,7 @@ static int shell_fg_bg(struct job *cmd, struct jobSet *jobList);
 static int shell_help(struct job *cmd, struct jobSet *junk);
 static int shell_jobs(struct job *dummy, struct jobSet *jobList);
 static int shell_pwd(struct job *dummy, struct jobSet *junk);
-static int shell_set(struct job *cmd, struct jobSet *junk);
+static int shell_export(struct job *cmd, struct jobSet *junk);
 static int shell_source(struct job *cmd, struct jobSet *jobList);
 static int shell_unset(struct job *cmd, struct jobSet *junk);
 
@@ -120,7 +120,7 @@ static struct builtInCommand bltins[] = {
        {"fg", "Bring job into the foreground", "fg [%%job]", shell_fg_bg},
        {"jobs", "Lists the active jobs", "jobs", shell_jobs},
        {"pwd", "Print current directory", "pwd", shell_pwd},
-       {"set", "Set environment variable", "set [VAR=value]", shell_set},
+       {"export", "Set environment variable", "export [VAR=value]", shell_export},
        {"unset", "Unset environment variable", "unset VAR", shell_unset},
        
                {".", "Source-in and run commands in a file", ". filename",
@@ -182,7 +182,7 @@ static int shell_exit(struct job *cmd, struct jobSet *junk)
 static int shell_fg_bg(struct job *cmd, struct jobSet *jobList)
 {
        int i, jobNum;
-       struct job *job;
+       struct job *job=NULL;
 
        if (!jobList->head) {
                if (!cmd->progs[0].argv[1] || cmd->progs[0].argv[2]) {
@@ -268,8 +268,8 @@ static int shell_pwd(struct job *dummy, struct jobSet *junk)
        return TRUE;
 }
 
-/* built-in 'set VAR=value' handler */
-static int shell_set(struct job *cmd, struct jobSet *junk)
+/* built-in 'export VAR=value' handler */
+static int shell_export(struct job *cmd, struct jobSet *junk)
 {
        int res;
 
@@ -278,7 +278,7 @@ static int shell_set(struct job *cmd, struct jobSet *junk)
        }
        res = putenv(cmd->progs[0].argv[1]);
        if (res)
-               fprintf(stdout, "set: %s\n", strerror(errno));
+               fprintf(stdout, "export: %s\n", strerror(errno));
        return (res);
 }
 
index 8a99e0f9e99d016044a8c85974a91d3a787ee5e2..10343a150ad6bd170bf78e4f63c680544f9d0bb9 100644 (file)
@@ -36,11 +36,12 @@ static const char *kill_usage =
        "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
        "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
 
+#ifdef BB_KILLALL
 static const char *killall_usage =
        "killall [-signal] process-name [process-name ...]\n\n"
        "Send a signal (default is SIGTERM) to the specified process(es).\n\n"
        "Options:\n" "\t-l\tList all signal names and numbers.\n\n";
-
+#endif
 
 #define KILL   0
 #define KILLALL        1
@@ -132,10 +133,15 @@ extern int kill_main(int argc, char **argv)
        int whichApp, sig = SIGTERM;
        const char *appUsage;
 
+#ifdef BB_KILLALL
        /* Figure out what we are trying to do here */
        whichApp = (strcmp(*argv, "killall") == 0)? 
                KILLALL : KILL; 
        appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
+#else
+       whichApp = KILL;
+       appUsage = kill_usage;
+#endif
 
        argc--;
        argv++;
@@ -213,7 +219,9 @@ extern int kill_main(int argc, char **argv)
                                fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
                        argv++;
                }
-       } else {
+       } 
+#ifdef BB_KILLALL
+       else {
                /* Looks like they want to do a killall.  Do that */
                while (--argc >= 0) {
                        int pid;
@@ -225,6 +233,7 @@ extern int kill_main(int argc, char **argv)
                        argv++;
                }
        }
+#endif
 
        exit(TRUE);
 
diff --git a/sh.c b/sh.c
index e143cfe740393c2ac1a51c127104b3559ef12873..068159697f7d028288ada542e36df83c689c14b3 100644 (file)
--- a/sh.c
+++ b/sh.c
@@ -98,7 +98,7 @@ static int shell_fg_bg(struct job *cmd, struct jobSet *jobList);
 static int shell_help(struct job *cmd, struct jobSet *junk);
 static int shell_jobs(struct job *dummy, struct jobSet *jobList);
 static int shell_pwd(struct job *dummy, struct jobSet *junk);
-static int shell_set(struct job *cmd, struct jobSet *junk);
+static int shell_export(struct job *cmd, struct jobSet *junk);
 static int shell_source(struct job *cmd, struct jobSet *jobList);
 static int shell_unset(struct job *cmd, struct jobSet *junk);
 
@@ -120,7 +120,7 @@ static struct builtInCommand bltins[] = {
        {"fg", "Bring job into the foreground", "fg [%%job]", shell_fg_bg},
        {"jobs", "Lists the active jobs", "jobs", shell_jobs},
        {"pwd", "Print current directory", "pwd", shell_pwd},
-       {"set", "Set environment variable", "set [VAR=value]", shell_set},
+       {"export", "Set environment variable", "export [VAR=value]", shell_export},
        {"unset", "Unset environment variable", "unset VAR", shell_unset},
        
                {".", "Source-in and run commands in a file", ". filename",
@@ -182,7 +182,7 @@ static int shell_exit(struct job *cmd, struct jobSet *junk)
 static int shell_fg_bg(struct job *cmd, struct jobSet *jobList)
 {
        int i, jobNum;
-       struct job *job;
+       struct job *job=NULL;
 
        if (!jobList->head) {
                if (!cmd->progs[0].argv[1] || cmd->progs[0].argv[2]) {
@@ -268,8 +268,8 @@ static int shell_pwd(struct job *dummy, struct jobSet *junk)
        return TRUE;
 }
 
-/* built-in 'set VAR=value' handler */
-static int shell_set(struct job *cmd, struct jobSet *junk)
+/* built-in 'export VAR=value' handler */
+static int shell_export(struct job *cmd, struct jobSet *junk)
 {
        int res;
 
@@ -278,7 +278,7 @@ static int shell_set(struct job *cmd, struct jobSet *junk)
        }
        res = putenv(cmd->progs[0].argv[1]);
        if (res)
-               fprintf(stdout, "set: %s\n", strerror(errno));
+               fprintf(stdout, "export: %s\n", strerror(errno));
        return (res);
 }
 
index d1604f1d1dc41423bcfe03bc1cfb90d135b44867..314e8cd661804940a03a4c15a61162911f7c57e6 100644 (file)
@@ -47,6 +47,8 @@
 
 #define ESC    27
 #define DEL    127
+#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
 
 static struct history *his_front = NULL;       /* First element in command line list */
 static struct history *his_end = NULL; /* Last element in command line list */
@@ -104,7 +106,7 @@ void cmdedit_reset_term(void)
        xioctl(fileno(stdin), TCSETA, (void *) &old_term);
 }
 
-void gotaSignal(int sig)
+void prepareToDie(int sig)
 {
     cmdedit_reset_term();
     fprintf(stdout, "\n");
@@ -175,6 +177,40 @@ void input_backspace(int outputFd, int *cursor, int *len)
     }
 }
 
+char **username_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin username_completion_matches\n");
+    return ( (char**) NULL);
+}
+char **command_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin command_completion_matches\n");
+    return ( (char**) NULL);
+}
+char **directory_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin directory_completion_matches\n");
+    return ( (char**) NULL);
+}
+
+/*
+ * This function is used to grab a character buffer
+ * from the input file descriptor and allows you to
+ * a string with full command editing (sortof like
+ * a mini readline).
+ *
+ * The following standard commands are not implemented:
+ * ESC-b -- Move back one word
+ * ESC-f -- Move forward one word
+ * ESC-d -- Delete back one word
+ * ESC-h -- Delete forward one word
+ * CTL-t -- Transpose two characters
+ *
+ * Furthermore, the "vi" command editing keys are not implemented.
+ *
+ * TODO: implement TAB command completion. :)
+ *
+ */
 extern int cmdedit_read_input(int inputFd, int outputFd,
                            char command[BUFSIZ])
 {
@@ -185,6 +221,8 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
     int cursor = 0;
     int break_out = 0;
     int ret = 0;
+    int lastWasTab = FALSE;
+    char **matches = (char **)NULL;
     char c = 0;
     struct history *hp = his_end;
 
@@ -209,90 +247,233 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
 
        if ((ret = read(inputFd, &c, 1)) < 1)
            return ret;
-
+       
        switch (c) {
-       case 1:         /* Control-A Beginning of line */
+       case 1:         
+           /* Control-a -- Beginning of line */
            input_home(outputFd, &cursor);
-           break;
-       case 5:         /* Control-E EOL */
+       case 5:         
+           /* Control-e -- End of line */
            input_end(outputFd, &cursor, len);
            break;
-       case 4:         /* Control-D */
+       case 2:
+           /* Control-b -- Move back one character */
+           if (cursor > 0) {
+               xwrite(outputFd, "\033[D", 3);
+               cursor--;
+           }
+           break;
+       case 6: 
+           /* Control-f -- Move forward one character */
+           if (cursor < len) {
+               xwrite(outputFd, "\033[C", 3);
+               cursor++;
+           }
+           break;
+       case 4:
+           /* Control-d -- Delete one character */
            if (cursor != len) {
                input_delete(outputFd, cursor);
                len--;
+           } else if (len == 0) {
+               prepareToDie(0);
+               exit(0);
+           }
+           break;
+       case 14:
+           /* Control-n -- Get next command */
+           if (hp && hp->n && hp->n->s) {      
+               free( hp->s);
+               hp->s = strdup(parsenextc);
+               hp = hp->n;
+               goto hop;
            }
            break;
-       case '\b':              /* Backspace */
+       case 16:
+           /* Control-p -- Get previous command */
+           if (hp && hp->p) {  
+               free( hp->s);
+               hp->s = strdup(parsenextc);
+               hp = hp->p;
+               goto hop;
+           }
+           break;
+       case '\t':
+           {
+           /* Do TAB completion */
+               int in_command_position=0, ti=len-1;
+
+               if (lastWasTab == FALSE) {
+                   char *tmp;
+                   char *matchBuf;
+
+                   if (matches) {
+                       free(matches);
+                       matches = (char **)NULL;
+                   }
+
+                   matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
+
+                   /* Make a local copy of the string -- up 
+                    * to the the position of the cursor */
+                   strcpy( matchBuf, parsenextc); 
+                   matchBuf[cursor+1] = '\0';
+
+                   /* skip leading white space */
+                   tmp = matchBuf;
+                   while (*tmp && isspace(*tmp)) {
+                       (tmp)++;
+                       ti++;
+                   }
+
+                   /* Determine if this is a command word or not */
+                   //while ((ti > -1) && (whitespace (matchBuf[ti]))) {
+//printf("\nti=%d\n", ti);
+               //      ti--;
+                //   }
+printf("\nti=%d\n", ti);
+
+                   if (ti < 0) {
+                         in_command_position++;
+                   } else if (member(matchBuf[ti], ";|&{(`")) {
+                       int this_char, prev_char;
+                       in_command_position++;
+                       /* Handle the two character tokens `>&', `<&', and `>|'.
+                        We are not in a command position after one of these. */
+                       this_char = matchBuf[ti];
+                       prev_char = matchBuf[ti - 1];
+
+                       if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
+                               (this_char == '|' && prev_char == '>')) {
+                           in_command_position = 0;
+                       } 
+                       /* For now, do not bother with catching quoted
+                        * expressions and marking them as not in command
+                        * positions.  Some other day.  Or not.
+                        */
+                       //else if (char_is_quoted (matchBuf, ti)) {
+                       //    in_command_position = 0;
+                       //}
+                   }
+printf("\nin_command_position=%d\n", in_command_position);
+                   /* If the word starts in `~', and there is no slash in the word, 
+                    * then try completing this word as a username. */
+                   if (*matchBuf == '~' && !strchr (matchBuf, '/'))
+                       matches = username_completion_matches(matchBuf);
+
+                   /* If this word is in a command position, then complete over possible 
+                    * command names, including aliases, built-ins, and executables. */
+                   if (!matches && in_command_position) {
+                       matches = command_completion_matches(matchBuf);
+
+                   /* If we are attempting command completion and nothing matches, 
+                    * then try and match directories as a last resort... */
+                   if (!matches)
+                       matches = directory_completion_matches(matchBuf);
+                   }
+               } else {
+                   printf("\nprinting match list\n");
+               }
+               /* Rewrite the whole line (for debugging) */
+               for (; cursor > 0; cursor--)    
+                   xwrite(outputFd, "\b", 1);
+               len = strlen(parsenextc);
+               xwrite(outputFd, parsenextc, len);
+               cursor = len;
+               break;
+           }
+       case '\b':              
        case DEL:
+           /* Backspace */
            input_backspace(outputFd, &cursor, &len);
            break;
-       case '\n':              /* Enter */
+       case '\n':              
+           /* Enter */
            *(parsenextc + len++ + 1) = c;
            xwrite(outputFd, &c, 1);
            break_out = 1;
            break;
-       case ESC:               /* escape sequence follows */
+       case ESC:               {
+           /* escape sequence follows */
            if ((ret = read(inputFd, &c, 1)) < 1)
                return ret;
 
            if (c == '[') {     /* 91 */
                if ((ret = read(inputFd, &c, 1)) < 1)
                    return ret;
-
+               
                switch (c) {
                case 'A':
-                   if (hp && hp->p) {  /* Up */
+                   /* Up Arrow -- Get previous command */
+                   if (hp && hp->p) {  
+                       free( hp->s);
+                       hp->s = strdup(parsenextc);
                        hp = hp->p;
                        goto hop;
                    }
                    break;
                case 'B':
-                   if (hp && hp->n && hp->n->s) {      /* Down */
+                   /* Down Arrow -- Get next command */
+                   if (hp && hp->n && hp->n->s) {      
+                       free( hp->s);
+                       hp->s = strdup(parsenextc);
                        hp = hp->n;
                        goto hop;
                    }
                    break;
 
-                 hop:          /* hop */
+                   /* This is where we rewrite the line 
+                    * using the selected history item */
+                 hop:          
                    len = strlen(parsenextc);
 
-                   for (; cursor > 0; cursor--)        /* return to begining of line */
+                   /* return to begining of line */
+                   for (; cursor > 0; cursor--)        
                        xwrite(outputFd, "\b", 1);
+                   xwrite(outputFd, parsenextc, len);
 
-                   for (j = 0; j < len; j++)   /* erase old command */
+                   /* erase old command */
+                   for (j = 0; j < len; j++)   
                        xwrite(outputFd, " ", 1);
 
-                   for (j = len; j > 0; j--)   /* return to begining of line */
+                   /* return to begining of line */
+                   for (j = len; j > 0; j--)   
                        xwrite(outputFd, "\b", 1);
 
-                   strcpy(parsenextc, hp->s);  /* write new command */
+                   memset(parsenextc, 0, BUFSIZ);
+                   /* write new command */
+                   strcpy(parsenextc, hp->s);  
                    len = strlen(hp->s);
                    xwrite(outputFd, parsenextc, len);
                    cursor = len;
                    break;
-               case 'C':       /* Right */
+               case 'C':       
+                   /* Right Arrow -- Move forward one character */
                    if (cursor < len) {
                        xwrite(outputFd, "\033[C", 3);
                        cursor++;
                    }
                    break;
-               case 'D':       /* Left */
+               case 'D':       
+                   /* Left Arrow -- Move back one character */
                    if (cursor > 0) {
                        xwrite(outputFd, "\033[D", 3);
                        cursor--;
                    }
                    break;
-               case '3':       /* Delete */
+               case '3':       
+                   /* Delete */
                    if (cursor != len) {
                        input_delete(outputFd, cursor);
                        len--;
                    }
                    break;
-               case '1':       /* Home (Ctrl-A) */
+               case '1':       
+                   /* Home (Ctrl-A) */
                    input_home(outputFd, &cursor);
                    break;
-               case '4':       /* End (Ctrl-E) */
+               case '4':       
+                   /* End (Ctrl-E) */
                    input_end(outputFd, &cursor, len);
                    break;
                }
@@ -300,20 +481,24 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
                    if ((ret = read(inputFd, &c, 1)) < 1)
                        return ret;     /* read 126 (~) */
            }
-           if (c == 'O') {     /* 79 */
+           if (c == 'O') {     
+               /* 79 */
                if ((ret = read(inputFd, &c, 1)) < 1)
                    return ret;
                switch (c) {
-               case 'H':       /* Home (xterm) */
+               case 'H':       
+                   /* Home (xterm) */
                    input_home(outputFd, &cursor);
                    break;
-               case 'F':       /* End (xterm) */
+               case 'F':       
+                   /* End (xterm) */
                    input_end(outputFd, &cursor, len);
                    break;
                }
            }
            c = 0;
            break;
+       }
 
        default:                /* If it's regular input, do the normal thing */
 
@@ -343,6 +528,10 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
            xwrite(outputFd, &c, 1);
            break;
        }
+       if (c=='\t')
+           lastWasTab = TRUE;
+       else
+           lastWasTab = FALSE;
 
        if (break_out)          /* Enter is the command terminator, no more input. */
            break;
@@ -353,32 +542,33 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
     reset_term = 0;
 
 
-    if (*(parsenextc)) {       /* Handle command history log */
+    /* Handle command history log */
+    if (*(parsenextc)) {       
 
        struct history *h = his_end;
 
-       if (!h) {               /* No previous history */
+       if (!h) {               
+           /* No previous history */
            h = his_front = malloc(sizeof(struct history));
            h->n = malloc(sizeof(struct history));
            h->p = NULL;
            h->s = strdup(parsenextc);
-
            h->n->p = h;
            h->n->n = NULL;
            h->n->s = NULL;
            his_end = h->n;
            history_counter++;
-       } else {                /* Add a new history command */
-
+       } else {                
+           /* Add a new history command */
            h->n = malloc(sizeof(struct history));
-
            h->n->p = h;
            h->n->n = NULL;
            h->n->s = NULL;
            h->s = strdup(parsenextc);
            his_end = h->n;
 
-           if (history_counter >= MAX_HISTORY) {       /* After max history, remove the last known command */
+           /* After max history, remove the oldest command */
+           if (history_counter >= MAX_HISTORY) {       
 
                struct history *p = his_front->n;
 
@@ -398,8 +588,8 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
 extern void cmdedit_init(void)
 {
     atexit(cmdedit_reset_term);
-    signal(SIGINT, gotaSignal);
-    signal(SIGQUIT, gotaSignal);
-    signal(SIGTERM, gotaSignal);
+    signal(SIGINT, prepareToDie);
+    signal(SIGQUIT, prepareToDie);
+    signal(SIGTERM, prepareToDie);
 }
 #endif                         /* BB_FEATURE_SH_COMMAND_EDITING */
index e143cfe740393c2ac1a51c127104b3559ef12873..068159697f7d028288ada542e36df83c689c14b3 100644 (file)
@@ -98,7 +98,7 @@ static int shell_fg_bg(struct job *cmd, struct jobSet *jobList);
 static int shell_help(struct job *cmd, struct jobSet *junk);
 static int shell_jobs(struct job *dummy, struct jobSet *jobList);
 static int shell_pwd(struct job *dummy, struct jobSet *junk);
-static int shell_set(struct job *cmd, struct jobSet *junk);
+static int shell_export(struct job *cmd, struct jobSet *junk);
 static int shell_source(struct job *cmd, struct jobSet *jobList);
 static int shell_unset(struct job *cmd, struct jobSet *junk);
 
@@ -120,7 +120,7 @@ static struct builtInCommand bltins[] = {
        {"fg", "Bring job into the foreground", "fg [%%job]", shell_fg_bg},
        {"jobs", "Lists the active jobs", "jobs", shell_jobs},
        {"pwd", "Print current directory", "pwd", shell_pwd},
-       {"set", "Set environment variable", "set [VAR=value]", shell_set},
+       {"export", "Set environment variable", "export [VAR=value]", shell_export},
        {"unset", "Unset environment variable", "unset VAR", shell_unset},
        
                {".", "Source-in and run commands in a file", ". filename",
@@ -182,7 +182,7 @@ static int shell_exit(struct job *cmd, struct jobSet *junk)
 static int shell_fg_bg(struct job *cmd, struct jobSet *jobList)
 {
        int i, jobNum;
-       struct job *job;
+       struct job *job=NULL;
 
        if (!jobList->head) {
                if (!cmd->progs[0].argv[1] || cmd->progs[0].argv[2]) {
@@ -268,8 +268,8 @@ static int shell_pwd(struct job *dummy, struct jobSet *junk)
        return TRUE;
 }
 
-/* built-in 'set VAR=value' handler */
-static int shell_set(struct job *cmd, struct jobSet *junk)
+/* built-in 'export VAR=value' handler */
+static int shell_export(struct job *cmd, struct jobSet *junk)
 {
        int res;
 
@@ -278,7 +278,7 @@ static int shell_set(struct job *cmd, struct jobSet *junk)
        }
        res = putenv(cmd->progs[0].argv[1]);
        if (res)
-               fprintf(stdout, "set: %s\n", strerror(errno));
+               fprintf(stdout, "export: %s\n", strerror(errno));
        return (res);
 }
 
index 4b26a1b76b5993fc4056acaf1266009ad865387d..c274bfa1536e4f72318172b50c8666dadb21c7bd 100644 (file)
--- a/utility.c
+++ b/utility.c
@@ -1247,8 +1247,7 @@ extern int device_open(char *device, int mode)
 #endif                                                 /* BB_INIT BB_SYSLOGD */
 
 
-#if defined BB_FEATURE_LINUXRC && ( defined BB_HALT || defined BB_REBOOT || defined BB_POWEROFF )
-
+#if defined BB_KILLALL || ( defined BB_FEATURE_LINUXRC && ( defined BB_HALT || defined BB_REBOOT || defined BB_POWEROFF ))
 #ifdef BB_FEATURE_USE_DEVPS_PATCH
 #include <linux/devps.h>
 #endif
@@ -1363,7 +1362,7 @@ extern pid_t findPidByName( char* pidName)
        return 0;
 }
 #endif                                                 /* BB_FEATURE_USE_DEVPS_PATCH */
-#endif                                                 /* BB_INIT || BB_HALT || BB_REBOOT || BB_POWEROFF */
+#endif                                                 /* BB_KILLALL || ( BB_FEATURE_LINUXRC && ( BB_HALT || BB_REBOOT || BB_POWEROFF )) */
 
 #if defined BB_GUNZIP \
  || defined BB_GZIP   \