summaryrefslogtreecommitdiff
path: root/shell/lash.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-03-08 23:59:45 +0000
committerEric Andersen <andersen@codepoet.org>2001-03-08 23:59:45 +0000
commit13d1fa1d01e48c7a23cc1114fc4d45b20f2c48eb (patch)
tree2facfcfcd614fe7d935e167820f202e739196bc0 /shell/lash.c
parentdf351d6109fb1846e5d18fa89e91ee050a7de334 (diff)
downloadbusybox-w32-13d1fa1d01e48c7a23cc1114fc4d45b20f2c48eb.tar.gz
busybox-w32-13d1fa1d01e48c7a23cc1114fc4d45b20f2c48eb.tar.bz2
busybox-w32-13d1fa1d01e48c7a23cc1114fc4d45b20f2c48eb.zip
Add in 'trim' routine. Fix up sh.c so it works when wordexp
is not available. -Erik
Diffstat (limited to 'shell/lash.c')
-rw-r--r--shell/lash.c96
1 files changed, 85 insertions, 11 deletions
diff --git a/shell/lash.c b/shell/lash.c
index 65a0a25d2..8b7981b4d 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -54,16 +54,25 @@
54#include <ctype.h> 54#include <ctype.h>
55#include <errno.h> 55#include <errno.h>
56#include <fcntl.h> 56#include <fcntl.h>
57#include <wordexp.h>
58#include <signal.h> 57#include <signal.h>
59#include <string.h> 58#include <string.h>
60#include <sys/ioctl.h> 59#include <sys/ioctl.h>
61#include <sys/wait.h> 60#include <sys/wait.h>
62#include <unistd.h> 61#include <unistd.h>
63#include <getopt.h> 62#include <getopt.h>
63
64#if ( (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) ) || defined (__UCLIBC__)
65#include <wordexp.h>
66#define expand_t wordexp_t
67#undef BB_FEATURE_SH_BACKTICKS
68#else
69#include <glob.h>
70#define expand_t glob_t
71#endif
64#include "busybox.h" 72#include "busybox.h"
65#include "cmdedit.h" 73#include "cmdedit.h"
66 74
75
67static const int MAX_LINE = 256; /* size of input buffer for cwd data */ 76static const int MAX_LINE = 256; /* size of input buffer for cwd data */
68static const int MAX_READ = 128; /* size of input buffer for `read' builtin */ 77static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
69#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" 78#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
@@ -901,7 +910,7 @@ static char* itoa(register int i)
901static int expand_arguments(char *command) 910static int expand_arguments(char *command)
902{ 911{
903#ifdef BB_FEATURE_SH_ENVIRONMENT 912#ifdef BB_FEATURE_SH_ENVIRONMENT
904 wordexp_t wrdexp; 913 expand_t expand_result;
905 char *src, *dst, *var; 914 char *src, *dst, *var;
906 int i=0, length, total_length=0, retval; 915 int i=0, length, total_length=0, retval;
907#endif 916#endif
@@ -911,14 +920,14 @@ static int expand_arguments(char *command)
911 920
912#ifdef BB_FEATURE_SH_ENVIRONMENT 921#ifdef BB_FEATURE_SH_ENVIRONMENT
913 922
923
924#if ( (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) ) || defined (__UCLIBC__)
914 /* This first part uses wordexp() which is a wonderful C lib 925 /* This first part uses wordexp() which is a wonderful C lib
915 * function which expands nearly everything. */ 926 * function which expands nearly everything. */
916 927 retval = wordexp (command, &expand_result, 0);
917 retval = wordexp (command, &wrdexp, 0);
918
919 if (retval == WRDE_NOSPACE) { 928 if (retval == WRDE_NOSPACE) {
920 /* Mem may have been allocated... */ 929 /* Mem may have been allocated... */
921 wordfree (&wrdexp); 930 wordfree (&expand_result);
922 error_msg("out of space during expansion"); 931 error_msg("out of space during expansion");
923 return FALSE; 932 return FALSE;
924 } 933 }
@@ -931,23 +940,88 @@ static int expand_arguments(char *command)
931 /* Convert from char** (one word per string) to a simple char*, 940 /* Convert from char** (one word per string) to a simple char*,
932 * but don't overflow command which is BUFSIZ in length */ 941 * but don't overflow command which is BUFSIZ in length */
933 *command = '\0'; 942 *command = '\0';
934 while (i < wrdexp.we_wordc && total_length < BUFSIZ) { 943 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
935 length=strlen(wrdexp.we_wordv[i])+1; 944 length=strlen(expand_result.we_wordv[i])+1;
936 if (BUFSIZ-total_length-length <= 0) { 945 if (BUFSIZ-total_length-length <= 0) {
937 error_msg("out of space during expansion"); 946 error_msg("out of space during expansion");
938 return FALSE; 947 return FALSE;
939 } 948 }
940 strcat(command+total_length, wrdexp.we_wordv[i++]); 949 strcat(command+total_length, expand_result.we_wordv[i++]);
941 strcat(command+total_length, " "); 950 strcat(command+total_length, " ");
942 total_length+=length; 951 total_length+=length;
943 } 952 }
944 wordfree (&wrdexp); 953 wordfree (&expand_result);
954#else
955
956 /* Ok. They don't have glibc and they don't have uClibc. Chances are
957 * about 100% they don't have wordexp(), so instead, the best we can do is
958 * use glob, which is better then nothing, but certainly not perfect */
959
960 /* It turns out that glob is very stupid. We have to feed it
961 * one word at a time since it can't cope with a full string.
962 * Here we convert command (char*) into cmd (char**, one word
963 * per string) */
964 {
965
966 int flags = GLOB_NOCHECK|GLOB_BRACE|GLOB_TILDE;
967 char * tmpcmd;
968 /* We need a clean copy, so strsep can mess up the copy while
969 * we write stuff into the original in a minute */
970 char * cmd = strdup(command);
971 for (tmpcmd = cmd; (tmpcmd = strsep(&cmd, " \t")) != NULL;) {
972 if (*tmpcmd == '\0')
973 break;
974 retval = glob(tmpcmd, flags, NULL, &expand_result);
975 /* We can't haveGLOB_APPEND on the first glob call,
976 * so put it there now */
977 if (! (flags & GLOB_APPEND) )
978 flags |= GLOB_APPEND;
979
980 if (retval == GLOB_NOSPACE) {
981 /* Mem may have been allocated... */
982 globfree (&expand_result);
983 error_msg("out of space during expansion");
984 return FALSE;
985 }
986 if (retval == GLOB_ABORTED || retval == GLOB_NOSYS) {
987 /* Some other error. */
988 error_msg("syntax error");
989 return FALSE;
990 }
991
992 /* Convert from char** (one word per string) to a simple char*,
993 * but don't overflow command which is BUFSIZ in length */
994 *command = '\0';
995 if ( expand_result.gl_pathc > 1) {
996 while (i < expand_result.gl_pathc && total_length < BUFSIZ) {
997 length=strlen(expand_result.gl_pathv[i])+1;
998 if (BUFSIZ-total_length-length <= 0) {
999 error_msg("out of space during expansion");
1000 return FALSE;
1001 }
1002 strcat(command+total_length, expand_result.gl_pathv[i++]);
1003 strcat(command+total_length, " ");
1004 total_length+=length;
1005 }
1006 }
1007 }
1008
1009 free(cmd);
1010 globfree (&expand_result);
1011 }
1012
1013#endif
945 1014
1015 /* FIXME -- this routine (which is only used when folks
1016 * don't have a C library with wordexp) needs a bit of help
1017 * to handle things like 'echo $PATH$0' */
946 1018
947 /* Now do the shell variable substitutions which 1019 /* Now do the shell variable substitutions which
948 * wordexp can't do for us, namely $? and $! */ 1020 * wordexp can't do for us, namely $? and $! */
949 src = command; 1021 src = command;
950 while((dst = strchr(src,'$')) != NULL){ 1022 while((dst = strchr(src,'$')) != NULL){
1023 /* Ok -- got a $ -- now clean up any trailing mess */
1024 trim(dst);
951 if (!(var = getenv(dst + 1))) { 1025 if (!(var = getenv(dst + 1))) {
952 switch(*(dst+1)) { 1026 switch(*(dst+1)) {
953 case '?': 1027 case '?':
@@ -995,7 +1069,7 @@ static int expand_arguments(char *command)
995 * the created gap with the new stuff */ 1069 * the created gap with the new stuff */
996 memmove(dst+subst_len, next_dst+1, subst_len); 1070 memmove(dst+subst_len, next_dst+1, subst_len);
997 /* Now copy in the new stuff */ 1071 /* Now copy in the new stuff */
998 strncpy(dst, var, subst_len); 1072 strncpy(dst, var, subst_len+1);
999 src = dst; 1073 src = dst;
1000 src++; 1074 src++;
1001 } else { 1075 } else {