f2d76cc01da2e8e2729fca62818a4df926103916
[oweals/busybox.git] / shell / bbsh.c
1 /* vi: set ts=4 :
2  * 
3  * bbsh - busybox shell
4  *
5  * Copyright 2006 Rob Landley <rob@landley.net>
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8  */
9
10 // Handle embedded NUL bytes in the command line.
11
12 #include <busybox.h>
13
14 static int handle(char *command)
15 {
16         int argc=0;
17         char *argv[10], *start = command;
18
19         // Parse command into argv[]
20         for (;;) {
21                 char *end;
22
23                 // Skip leading whitespace and detect EOL.
24                 while(isspace(*start)) start++;
25                 if(!*start || *start=='#') break;
26
27                 // Grab next word.  (Add dequote and envvar logic here)
28                 end=start;
29                 while(*end && !isspace(*end)) end++;
30                 argv[argc++]=xstrndup(start,end-start);
31                 start=end;
32         }
33         argv[argc]=0;
34
35         if (!argc) return 0;
36         if (argc==2 && !strcmp(argv[0],"cd")) chdir(argv[1]);
37         else if(!strcmp(argv[0],"exit")) exit(argc>1 ? atoi(argv[1]) : 0); 
38         else {
39                 int status;
40                 pid_t pid=fork();
41                 if(!pid) {
42                         run_applet_by_name(argv[0],argc,argv);
43                         execvp(argv[0],argv);
44                         printf("No %s",argv[0]);
45                         exit(1);
46                 } else waitpid(pid, &status, 0);
47         }
48         while(argc) free(argv[--argc]);
49
50         return 0;
51 }
52
53 int bbsh_main(int argc, char *argv[])
54 {
55         char *command=NULL;
56         FILE *f;
57
58         bb_getopt_ulflags(argc, argv, "c:", &command);
59
60         f = argv[optind] ? xfopen(argv[optind],"r") : NULL;
61         if (command) handle(command);
62         else {
63                 unsigned cmdlen=0;
64                 for (;;) {
65                         if(!f) putchar('$');
66                         if(1 > getline(&command,&cmdlen,f ? : stdin)) break;
67                         handle(command);
68                 }
69                 if (ENABLE_FEATURE_CLEAN_UP) free(command);
70         }
71                 
72         return 1;
73 }