diff options
| author | Eric Andersen <andersen@codepoet.org> | 2000-07-28 15:14:45 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2000-07-28 15:14:45 +0000 |
| commit | 501c88b245fdc63f3f2a044fd7704bb468db3904 (patch) | |
| tree | 3fff440532d8d380ae7e4f2933bc7163360f8279 /shell | |
| parent | 6a99aaf0208151b7f5e5058efaa409496e2b7c4b (diff) | |
| download | busybox-w32-501c88b245fdc63f3f2a044fd7704bb468db3904.tar.gz busybox-w32-501c88b245fdc63f3f2a044fd7704bb468db3904.tar.bz2 busybox-w32-501c88b245fdc63f3f2a044fd7704bb468db3904.zip | |
More sh updates (with related changes to everything else). Switched
to using getopt and cleaned up the resulting mess. if-then-else-fi
is now basically working (given a bunch of constraints).
-Erik
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/cmdedit.c | 25 | ||||
| -rw-r--r-- | shell/cmdedit.h | 1 | ||||
| -rw-r--r-- | shell/lash.c | 179 |
3 files changed, 143 insertions, 62 deletions
diff --git a/shell/cmdedit.c b/shell/cmdedit.c index 0ce64beeb..042064f1e 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c | |||
| @@ -84,6 +84,7 @@ static int cmdedit_termw = 80; /* actual terminal width */ | |||
| 84 | static int cmdedit_scroll = 27; /* width of EOL scrolling region */ | 84 | static int cmdedit_scroll = 27; /* width of EOL scrolling region */ |
| 85 | static int history_counter = 0; /* Number of commands in history list */ | 85 | static int history_counter = 0; /* Number of commands in history list */ |
| 86 | static int reset_term = 0; /* Set to true if the terminal needs to be reset upon exit */ | 86 | static int reset_term = 0; /* Set to true if the terminal needs to be reset upon exit */ |
| 87 | static int exithandler_set = 0; /* Set to true when atexit() has been called */ | ||
| 87 | 88 | ||
| 88 | struct history { | 89 | struct history { |
| 89 | char *s; | 90 | char *s; |
| @@ -709,10 +710,32 @@ extern void cmdedit_read_input(char* prompt, char command[BUFSIZ]) | |||
| 709 | 710 | ||
| 710 | extern void cmdedit_init(void) | 711 | extern void cmdedit_init(void) |
| 711 | { | 712 | { |
| 712 | atexit(cmdedit_reset_term); | 713 | if(exithandler_set == 0) { |
| 714 | atexit(cmdedit_reset_term); /* be sure to do this only once */ | ||
| 715 | exithandler_set = 1; | ||
| 716 | } | ||
| 713 | signal(SIGKILL, clean_up_and_die); | 717 | signal(SIGKILL, clean_up_and_die); |
| 714 | signal(SIGINT, clean_up_and_die); | 718 | signal(SIGINT, clean_up_and_die); |
| 715 | signal(SIGQUIT, clean_up_and_die); | 719 | signal(SIGQUIT, clean_up_and_die); |
| 716 | signal(SIGTERM, clean_up_and_die); | 720 | signal(SIGTERM, clean_up_and_die); |
| 717 | } | 721 | } |
| 722 | |||
| 723 | /* | ||
| 724 | ** Undo the effects of cmdedit_init() as good as we can: | ||
| 725 | ** I am not aware of a way to revoke an atexit() handler, | ||
| 726 | ** but, fortunately, our particular handler can be made | ||
| 727 | ** a no-op by setting reset_term = 0. | ||
| 728 | */ | ||
| 729 | extern void cmdedit_terminate(void) | ||
| 730 | { | ||
| 731 | cmdedit_reset_term(); | ||
| 732 | reset_term = 0; | ||
| 733 | signal(SIGKILL, SIG_DFL); | ||
| 734 | signal(SIGINT, SIG_DFL); | ||
| 735 | signal(SIGQUIT, SIG_DFL); | ||
| 736 | signal(SIGTERM, SIG_DFL); | ||
| 737 | } | ||
| 738 | |||
| 739 | |||
| 740 | |||
| 718 | #endif /* BB_FEATURE_SH_COMMAND_EDITING */ | 741 | #endif /* BB_FEATURE_SH_COMMAND_EDITING */ |
diff --git a/shell/cmdedit.h b/shell/cmdedit.h index b621ae8ec..27f7b5500 100644 --- a/shell/cmdedit.h +++ b/shell/cmdedit.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | typedef size_t (*cmdedit_strwidth_proc)(char *); | 11 | typedef size_t (*cmdedit_strwidth_proc)(char *); |
| 12 | 12 | ||
| 13 | void cmdedit_init(void); | 13 | void cmdedit_init(void); |
| 14 | void cmdedit_terminate(void); | ||
| 14 | void cmdedit_read_input(char* promptStr, char* command); /* read a line of input */ | 15 | void cmdedit_read_input(char* promptStr, char* command); /* read a line of input */ |
| 15 | void cmdedit_setwidth(int); /* specify width of screen */ | 16 | void cmdedit_setwidth(int); /* specify width of screen */ |
| 16 | void cmdedit_histadd(char *); /* adds entries to hist */ | 17 | void cmdedit_histadd(char *); /* adds entries to hist */ |
diff --git a/shell/lash.c b/shell/lash.c index e57567608..836fc9bab 100644 --- a/shell/lash.c +++ b/shell/lash.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | //#define BB_FEATURE_SH_BACKTICKS | 29 | //#define BB_FEATURE_SH_BACKTICKS |
| 30 | //#define BB_FEATURE_SH_IF_EXPRESSIONS | 30 | //#define BB_FEATURE_SH_IF_EXPRESSIONS |
| 31 | //#define BB_FEATURE_SH_ENVIRONMENT | 31 | //#define BB_FEATURE_SH_ENVIRONMENT |
| 32 | //#define DEBUG_SHELL | ||
| 32 | 33 | ||
| 33 | 34 | ||
| 34 | #include "internal.h" | 35 | #include "internal.h" |
| @@ -43,6 +44,7 @@ | |||
| 43 | #include <sys/ioctl.h> | 44 | #include <sys/ioctl.h> |
| 44 | #include <sys/wait.h> | 45 | #include <sys/wait.h> |
| 45 | #include <unistd.h> | 46 | #include <unistd.h> |
| 47 | #include <getopt.h> | ||
| 46 | #ifdef BB_FEATURE_SH_COMMAND_EDITING | 48 | #ifdef BB_FEATURE_SH_COMMAND_EDITING |
| 47 | #include "cmdedit.h" | 49 | #include "cmdedit.h" |
| 48 | #endif | 50 | #endif |
| @@ -172,8 +174,9 @@ static char **argv; | |||
| 172 | #ifdef BB_FEATURE_SH_ENVIRONMENT | 174 | #ifdef BB_FEATURE_SH_ENVIRONMENT |
| 173 | static int lastBgPid=-1; | 175 | static int lastBgPid=-1; |
| 174 | static int lastReturnCode=-1; | 176 | static int lastReturnCode=-1; |
| 177 | static int showXtrace=FALSE; | ||
| 175 | #endif | 178 | #endif |
| 176 | 179 | ||
| 177 | 180 | ||
| 178 | #ifdef BB_FEATURE_SH_COMMAND_EDITING | 181 | #ifdef BB_FEATURE_SH_COMMAND_EDITING |
| 179 | void win_changed(int junk) | 182 | void win_changed(int junk) |
| @@ -382,14 +385,23 @@ static int builtin_if(struct job *cmd, struct jobSet *jobList) | |||
| 382 | status=strlen(charptr1); | 385 | status=strlen(charptr1); |
| 383 | local_pending_command = xmalloc(status+1); | 386 | local_pending_command = xmalloc(status+1); |
| 384 | strncpy(local_pending_command, charptr1, status); | 387 | strncpy(local_pending_command, charptr1, status); |
| 385 | printf("'if' now running '%s'\n", charptr1); | 388 | local_pending_command[status]='\0'; |
| 389 | #ifdef DEBUG_SHELL | ||
| 390 | fprintf(stderr, "'if' now testing '%s'\n", local_pending_command); | ||
| 391 | #endif | ||
| 386 | status = busy_loop(NULL); /* Frees local_pending_command */ | 392 | status = busy_loop(NULL); /* Frees local_pending_command */ |
| 387 | printf("if test returned "); | 393 | #ifdef DEBUG_SHELL |
| 394 | fprintf(stderr, "if test returned "); | ||
| 395 | #endif | ||
| 388 | if (status == 0) { | 396 | if (status == 0) { |
| 389 | printf("TRUE\n"); | 397 | #ifdef DEBUG_SHELL |
| 398 | fprintf(stderr, "TRUE\n"); | ||
| 399 | #endif | ||
| 390 | cmd->jobContext |= IF_TRUE_CONTEXT; | 400 | cmd->jobContext |= IF_TRUE_CONTEXT; |
| 391 | } else { | 401 | } else { |
| 392 | printf("FALSE\n"); | 402 | #ifdef DEBUG_SHELL |
| 403 | fprintf(stderr, "FALSE\n"); | ||
| 404 | #endif | ||
| 393 | cmd->jobContext |= IF_FALSE_CONTEXT; | 405 | cmd->jobContext |= IF_FALSE_CONTEXT; |
| 394 | } | 406 | } |
| 395 | 407 | ||
| @@ -407,7 +419,7 @@ static int builtin_then(struct job *cmd, struct jobSet *junk) | |||
| 407 | return FALSE; | 419 | return FALSE; |
| 408 | } | 420 | } |
| 409 | /* If the if result was FALSE, skip the 'then' stuff */ | 421 | /* If the if result was FALSE, skip the 'then' stuff */ |
| 410 | if (cmd->jobContext & IF_TRUE_CONTEXT) { | 422 | if (cmd->jobContext & IF_FALSE_CONTEXT) { |
| 411 | return TRUE; | 423 | return TRUE; |
| 412 | } | 424 | } |
| 413 | 425 | ||
| @@ -418,7 +430,10 @@ static int builtin_then(struct job *cmd, struct jobSet *junk) | |||
| 418 | status=strlen(charptr1); | 430 | status=strlen(charptr1); |
| 419 | local_pending_command = xmalloc(status+1); | 431 | local_pending_command = xmalloc(status+1); |
| 420 | strncpy(local_pending_command, charptr1, status); | 432 | strncpy(local_pending_command, charptr1, status); |
| 421 | printf("'then' now running '%s'\n", charptr1); | 433 | local_pending_command[status]='\0'; |
| 434 | #ifdef DEBUG_SHELL | ||
| 435 | fprintf(stderr, "'then' now running '%s'\n", charptr1); | ||
| 436 | #endif | ||
| 422 | return( busy_loop(NULL)); | 437 | return( busy_loop(NULL)); |
| 423 | } | 438 | } |
| 424 | 439 | ||
| @@ -433,7 +448,7 @@ static int builtin_else(struct job *cmd, struct jobSet *junk) | |||
| 433 | return FALSE; | 448 | return FALSE; |
| 434 | } | 449 | } |
| 435 | /* If the if result was TRUE, skip the 'else' stuff */ | 450 | /* If the if result was TRUE, skip the 'else' stuff */ |
| 436 | if (cmd->jobContext & IF_FALSE_CONTEXT) { | 451 | if (cmd->jobContext & IF_TRUE_CONTEXT) { |
| 437 | return TRUE; | 452 | return TRUE; |
| 438 | } | 453 | } |
| 439 | 454 | ||
| @@ -444,7 +459,10 @@ static int builtin_else(struct job *cmd, struct jobSet *junk) | |||
| 444 | status=strlen(charptr1); | 459 | status=strlen(charptr1); |
| 445 | local_pending_command = xmalloc(status+1); | 460 | local_pending_command = xmalloc(status+1); |
| 446 | strncpy(local_pending_command, charptr1, status); | 461 | strncpy(local_pending_command, charptr1, status); |
| 447 | printf("'else' now running '%s'\n", charptr1); | 462 | local_pending_command[status]='\0'; |
| 463 | #ifdef DEBUG_SHELL | ||
| 464 | fprintf(stderr, "'else' now running '%s'\n", charptr1); | ||
| 465 | #endif | ||
| 448 | return( busy_loop(NULL)); | 466 | return( busy_loop(NULL)); |
| 449 | } | 467 | } |
| 450 | 468 | ||
| @@ -457,7 +475,9 @@ static int builtin_fi(struct job *cmd, struct jobSet *junk) | |||
| 457 | } | 475 | } |
| 458 | /* Clear out the if and then context bits */ | 476 | /* Clear out the if and then context bits */ |
| 459 | cmd->jobContext &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT); | 477 | cmd->jobContext &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT); |
| 460 | printf("Hit an fi -- jobContext=%d\n", cmd->jobContext); | 478 | #ifdef DEBUG_SHELL |
| 479 | fprintf(stderr, "Hit an fi -- jobContext=%d\n", cmd->jobContext); | ||
| 480 | #endif | ||
| 461 | return TRUE; | 481 | return TRUE; |
| 462 | } | 482 | } |
| 463 | #endif | 483 | #endif |
| @@ -633,12 +653,23 @@ static int getCommand(FILE * source, char *command) | |||
| 633 | if (source == stdin) { | 653 | if (source == stdin) { |
| 634 | #ifdef BB_FEATURE_SH_COMMAND_EDITING | 654 | #ifdef BB_FEATURE_SH_COMMAND_EDITING |
| 635 | int len; | 655 | int len; |
| 656 | |||
| 657 | /* | ||
| 658 | ** enable command line editing only while a command line | ||
| 659 | ** is actually being read; otherwise, we'll end up bequeathing | ||
| 660 | ** atexit() handlers and other unwanted stuff to our | ||
| 661 | ** child processes (rob@sysgo.de) | ||
| 662 | */ | ||
| 663 | cmdedit_init(); | ||
| 664 | signal(SIGWINCH, win_changed); | ||
| 636 | len=fprintf(stdout, "%s %s", cwd, prompt); | 665 | len=fprintf(stdout, "%s %s", cwd, prompt); |
| 637 | fflush(stdout); | 666 | fflush(stdout); |
| 638 | promptStr=(char*)xmalloc(sizeof(char)*(len+1)); | 667 | promptStr=(char*)xmalloc(sizeof(char)*(len+1)); |
| 639 | sprintf(promptStr, "%s %s", cwd, prompt); | 668 | sprintf(promptStr, "%s %s", cwd, prompt); |
| 640 | cmdedit_read_input(promptStr, command); | 669 | cmdedit_read_input(promptStr, command); |
| 641 | free( promptStr); | 670 | free( promptStr); |
| 671 | cmdedit_terminate(); | ||
| 672 | signal(SIGWINCH, SIG_DFL); | ||
| 642 | return 0; | 673 | return 0; |
| 643 | #else | 674 | #else |
| 644 | fprintf(stdout, "%s %s", cwd, prompt); | 675 | fprintf(stdout, "%s %s", cwd, prompt); |
| @@ -944,6 +975,7 @@ static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobLi | |||
| 944 | prog->numRedirections = 0; | 975 | prog->numRedirections = 0; |
| 945 | prog->redirections = NULL; | 976 | prog->redirections = NULL; |
| 946 | prog->freeGlob = 0; | 977 | prog->freeGlob = 0; |
| 978 | prog->isStopped = 0; | ||
| 947 | argc_l = 0; | 979 | argc_l = 0; |
| 948 | 980 | ||
| 949 | argvAlloced = 5; | 981 | argvAlloced = 5; |
| @@ -1108,10 +1140,20 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int | |||
| 1108 | } | 1140 | } |
| 1109 | } | 1141 | } |
| 1110 | 1142 | ||
| 1143 | #ifdef BB_FEATURE_SH_ENVIRONMENT | ||
| 1144 | if (showXtrace==TRUE) { | ||
| 1145 | int j; | ||
| 1146 | fprintf(stderr, "+ "); | ||
| 1147 | for (j = 0; newJob->progs[i].argv[j]; j++) | ||
| 1148 | fprintf(stderr, "%s ", newJob->progs[i].argv[j]); | ||
| 1149 | fprintf(stderr, "\n"); | ||
| 1150 | } | ||
| 1151 | #endif | ||
| 1152 | |||
| 1111 | /* Check if the command matches any non-forking builtins */ | 1153 | /* Check if the command matches any non-forking builtins */ |
| 1112 | for (x = bltins; x->cmd; x++) { | 1154 | for (x = bltins; x->cmd; x++) { |
| 1113 | if (strcmp(newJob->progs[i].argv[0], x->cmd) == 0 ) { | 1155 | if (strcmp(newJob->progs[i].argv[0], x->cmd) == 0 ) { |
| 1114 | return (x->function(newJob, jobList)); | 1156 | return(x->function(newJob, jobList)); |
| 1115 | } | 1157 | } |
| 1116 | } | 1158 | } |
| 1117 | 1159 | ||
| @@ -1130,6 +1172,7 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int | |||
| 1130 | dup2(nextout, 1); | 1172 | dup2(nextout, 1); |
| 1131 | dup2(nextout, 2); | 1173 | dup2(nextout, 2); |
| 1132 | close(nextout); | 1174 | close(nextout); |
| 1175 | close(pipefds[0]); | ||
| 1133 | } | 1176 | } |
| 1134 | 1177 | ||
| 1135 | /* explicit redirections override pipes */ | 1178 | /* explicit redirections override pipes */ |
| @@ -1138,18 +1181,18 @@ static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int | |||
| 1138 | /* Check if the command matches any of the other builtins */ | 1181 | /* Check if the command matches any of the other builtins */ |
| 1139 | for (x = bltins_forking; x->cmd; x++) { | 1182 | for (x = bltins_forking; x->cmd; x++) { |
| 1140 | if (strcmp(newJob->progs[i].argv[0], x->cmd) == 0) { | 1183 | if (strcmp(newJob->progs[i].argv[0], x->cmd) == 0) { |
| 1184 | applet_name=x->cmd; | ||
| 1141 | exit (x->function(newJob, jobList)); | 1185 | exit (x->function(newJob, jobList)); |
| 1142 | } | 1186 | } |
| 1143 | } | 1187 | } |
| 1144 | #ifdef BB_FEATURE_SH_STANDALONE_SHELL | 1188 | #ifdef BB_FEATURE_SH_STANDALONE_SHELL |
| 1145 | /* Check if the command matches any busybox internal commands here */ | 1189 | /* Check if the command matches any busybox internal commands here */ |
| 1146 | /* TODO: Add matching when paths are appended (i.e. 'cat' currently | ||
| 1147 | * works, but '/bin/cat' doesn't ) */ | ||
| 1148 | while (a->name != 0) { | 1190 | while (a->name != 0) { |
| 1149 | if (strcmp(newJob->progs[i].argv[0], a->name) == 0) { | 1191 | if (strcmp(get_last_path_component(newJob->progs[i].argv[0]), a->name) == 0) { |
| 1150 | int argc_l; | 1192 | int argc_l; |
| 1151 | char** argv=newJob->progs[i].argv; | 1193 | char** argv=newJob->progs[i].argv; |
| 1152 | for(argc_l=0;*argv!=NULL; argv++, argc_l++); | 1194 | for(argc_l=0;*argv!=NULL; argv++, argc_l++); |
| 1195 | applet_name=a->name; | ||
| 1153 | exit((*(a->main)) (argc_l, newJob->progs[i].argv)); | 1196 | exit((*(a->main)) (argc_l, newJob->progs[i].argv)); |
| 1154 | } | 1197 | } |
| 1155 | a++; | 1198 | a++; |
| @@ -1275,15 +1318,18 @@ static int busy_loop(FILE * input) | |||
| 1275 | jobList.fg->runningProgs--; | 1318 | jobList.fg->runningProgs--; |
| 1276 | jobList.fg->progs[i].pid = 0; | 1319 | jobList.fg->progs[i].pid = 0; |
| 1277 | 1320 | ||
| 1321 | #ifdef BB_FEATURE_SH_ENVIRONMENT | ||
| 1322 | lastReturnCode=WEXITSTATUS(status); | ||
| 1323 | #endif | ||
| 1324 | #if 0 | ||
| 1325 | printf("'%s' exited -- return code %d\n", jobList.fg->text, lastReturnCode); | ||
| 1326 | #endif | ||
| 1278 | if (!jobList.fg->runningProgs) { | 1327 | if (!jobList.fg->runningProgs) { |
| 1279 | /* child exited */ | 1328 | /* child exited */ |
| 1280 | 1329 | ||
| 1281 | removeJob(&jobList, jobList.fg); | 1330 | removeJob(&jobList, jobList.fg); |
| 1282 | jobList.fg = NULL; | 1331 | jobList.fg = NULL; |
| 1283 | } | 1332 | } |
| 1284 | #ifdef BB_FEATURE_SH_ENVIRONMENT | ||
| 1285 | lastReturnCode=WEXITSTATUS(status); | ||
| 1286 | #endif | ||
| 1287 | } else { | 1333 | } else { |
| 1288 | /* the child was stopped */ | 1334 | /* the child was stopped */ |
| 1289 | jobList.fg->stoppedProgs++; | 1335 | jobList.fg->stoppedProgs++; |
| @@ -1337,10 +1383,65 @@ void free_memory(void) | |||
| 1337 | 1383 | ||
| 1338 | int shell_main(int argc_l, char **argv_l) | 1384 | int shell_main(int argc_l, char **argv_l) |
| 1339 | { | 1385 | { |
| 1386 | int opt; | ||
| 1340 | FILE *input = stdin; | 1387 | FILE *input = stdin; |
| 1341 | argc = argc_l; | 1388 | argc = argc_l; |
| 1342 | argv = argv_l; | 1389 | argv = argv_l; |
| 1343 | 1390 | ||
| 1391 | |||
| 1392 | //if (argv[0] && argv[0][0] == '-') { | ||
| 1393 | // builtin_source("/etc/profile"); | ||
| 1394 | //} | ||
| 1395 | |||
| 1396 | while ((opt = getopt(argc, argv, "cx")) > 0) { | ||
| 1397 | switch (opt) { | ||
| 1398 | case 'c': | ||
| 1399 | input = NULL; | ||
| 1400 | local_pending_command = (char *) calloc(BUFSIZ, sizeof(char)); | ||
| 1401 | if (local_pending_command == 0) { | ||
| 1402 | fatalError("sh: out of memory\n"); | ||
| 1403 | } | ||
| 1404 | for(; optind<argc; optind++) | ||
| 1405 | { | ||
| 1406 | if (strlen(local_pending_command) + strlen(argv[optind]) >= BUFSIZ) { | ||
| 1407 | local_pending_command = realloc(local_pending_command, | ||
| 1408 | strlen(local_pending_command) + strlen(argv[optind])); | ||
| 1409 | if (local_pending_command==NULL) | ||
| 1410 | fatalError("sh: command too long\n"); | ||
| 1411 | } | ||
| 1412 | strcat(local_pending_command, argv[optind]); | ||
| 1413 | if ( (optind + 1) < argc) | ||
| 1414 | strcat(local_pending_command, " "); | ||
| 1415 | } | ||
| 1416 | break; | ||
| 1417 | case 'x': | ||
| 1418 | showXtrace = TRUE; | ||
| 1419 | break; | ||
| 1420 | default: | ||
| 1421 | usage(shell_usage); | ||
| 1422 | } | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | |||
| 1426 | if (optind<1 && input == stdin) { | ||
| 1427 | /* Looks like they want an interactive shell */ | ||
| 1428 | fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT); | ||
| 1429 | fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); | ||
| 1430 | } else if (1==(argc-optind)) { | ||
| 1431 | input = fopen(argv[optind], "r"); | ||
| 1432 | if (!input) { | ||
| 1433 | fatalError("%s: %s\n", argv[optind], strerror(errno)); | ||
| 1434 | } | ||
| 1435 | } else { | ||
| 1436 | char *oldpath, *newpath; | ||
| 1437 | oldpath = getenv("PATH"); | ||
| 1438 | newpath=(char*)xmalloc(strlen(oldpath)+12); | ||
| 1439 | snprintf(newpath, strlen(oldpath)+9, "PATH=./:%s", oldpath); | ||
| 1440 | putenv(newpath); | ||
| 1441 | execvp(argv[optind], argv+optind); | ||
| 1442 | fatalError("%s: %s\n", argv[optind], strerror(errno)); | ||
| 1443 | } | ||
| 1444 | |||
| 1344 | /* initialize the cwd -- this is never freed...*/ | 1445 | /* initialize the cwd -- this is never freed...*/ |
| 1345 | cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1); | 1446 | cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1); |
| 1346 | getcwd(cwd, sizeof(char)*MAX_LINE); | 1447 | getcwd(cwd, sizeof(char)*MAX_LINE); |
| @@ -1350,52 +1451,8 @@ int shell_main(int argc_l, char **argv_l) | |||
| 1350 | #endif | 1451 | #endif |
| 1351 | 1452 | ||
| 1352 | #ifdef BB_FEATURE_SH_COMMAND_EDITING | 1453 | #ifdef BB_FEATURE_SH_COMMAND_EDITING |
| 1353 | cmdedit_init(); | ||
| 1354 | signal(SIGWINCH, win_changed); | ||
| 1355 | win_changed(0); | 1454 | win_changed(0); |
| 1356 | #endif | 1455 | #endif |
| 1357 | 1456 | ||
| 1358 | //if (argv[0] && argv[0][0] == '-') { | ||
| 1359 | // builtin_source("/etc/profile"); | ||
| 1360 | //} | ||
| 1361 | |||
| 1362 | |||
| 1363 | if (argc < 2) { | ||
| 1364 | fprintf(stdout, "\n\nBusyBox v%s (%s) Built-in shell\n", BB_VER, BB_BT); | ||
| 1365 | fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n"); | ||
| 1366 | } else { | ||
| 1367 | if (argv[1][0]=='-' && argv[1][1]=='c') { | ||
| 1368 | int i; | ||
| 1369 | local_pending_command = (char *) calloc(BUFSIZ, sizeof(char)); | ||
| 1370 | if (local_pending_command == 0) { | ||
| 1371 | fatalError("out of memory\n"); | ||
| 1372 | } | ||
| 1373 | for(i=2; i<argc; i++) | ||
| 1374 | { | ||
| 1375 | if (strlen(local_pending_command) + strlen(argv[i]) >= BUFSIZ) { | ||
| 1376 | local_pending_command = realloc(local_pending_command, | ||
| 1377 | strlen(local_pending_command) + strlen(argv[i])); | ||
| 1378 | if (local_pending_command==NULL) | ||
| 1379 | fatalError("commands for -c option too long\n"); | ||
| 1380 | } | ||
| 1381 | strcat(local_pending_command, argv[i]); | ||
| 1382 | if ( (i + 1) < argc) | ||
| 1383 | strcat(local_pending_command, " "); | ||
| 1384 | } | ||
| 1385 | input = NULL; | ||
| 1386 | |||
| 1387 | } | ||
| 1388 | else if (argv[1][0]=='-') { | ||
| 1389 | usage(shell_usage); | ||
| 1390 | } | ||
| 1391 | else { | ||
| 1392 | input = fopen(argv[1], "r"); | ||
| 1393 | if (!input) { | ||
| 1394 | fatalError("Couldn't open file '%s': %s\n", argv[1], | ||
| 1395 | strerror(errno)); | ||
| 1396 | } | ||
| 1397 | } | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | return (busy_loop(input)); | 1457 | return (busy_loop(input)); |
| 1401 | } | 1458 | } |
