Skip to content

Commit 3cf04b0

Browse files
committed
Project: creating a shell
1 parent 58faec0 commit 3cf04b0

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#include <sys/types.h>
2+
#include <stdio.h>
3+
#include <unistd.h>
4+
#include <stdlib.h>
5+
6+
#define LSH_RL_BUFSIZE 1024 /* buffer size for reading user input */
7+
#define LSH_TOK_BUFSIZE 64
8+
#define LSH_TOK_DELIM " \t\r\n\a"
9+
10+
/* Function declarations for built-in shell commands */
11+
int lsh_cd(char **args);
12+
int lsh_help(char **args);
13+
int lsh_exit(char **args);
14+
15+
/* List of built-in commands, followed by their corresponding functions */
16+
char *builtin_str[] = {
17+
"cd",
18+
"help",
19+
"exit"
20+
};
21+
22+
int (*builtin_func[]) (char **) = {
23+
&lsh_cd,
24+
&lsh_help,
25+
&lsh_exit
26+
};
27+
28+
int lsh_num_builtins(){
29+
return sizeof(builtin_str) / sizeof(char *);
30+
}
31+
32+
/* Built-in function implementations */
33+
int lsh_cd(char **args)
34+
{
35+
if(args[1] == NULL){
36+
fprintf(stderr, "lsh: expected argument to \"cd\"\n");
37+
}else{
38+
if(chdir(args[1]) != 0){
39+
perror("lsh");
40+
}
41+
}
42+
43+
return 1;
44+
}
45+
46+
int lsh_help(char **args)
47+
{
48+
int i;
49+
printf("Aman Dalmia's LSH\n", );
50+
printf("Type program names and arguments, and press enter\n");
51+
printf("The following are built in:\n");
52+
53+
for(i = 0; i < lsh_num_builtins(); i++){
54+
printf(" %s\n", builtin_str[i]);
55+
}
56+
57+
printf("Use the man command for information on other programs.\n");
58+
return 1;
59+
}
60+
61+
int lsh_exit(char **args)
62+
{
63+
return 0;
64+
}
65+
66+
/* Launch a program */
67+
int lsh_launch(char **args){
68+
pid_t pid, wpid;
69+
int status;
70+
71+
pid = fork();
72+
if(pid == 0){ /* child process */
73+
if(execvp(args[0], args) == -1) perror("lsh");
74+
exit(EXIT_FAILURE);
75+
}else if(pid > 0){ /* parent process */
76+
do{
77+
wpid = waitpid(pid, &status, WUNTRACED);
78+
}while(!WIFEXITED(status) && !WIFSIGNALED(status));
79+
}else{ /* error forking */
80+
perror("lsh");
81+
}
82+
83+
return 1;
84+
}
85+
86+
/* Execute the parsed arguments */
87+
int lsh_execute(char **args){
88+
int i;
89+
90+
if(args[0] == NULL){ /* empty command was entered */
91+
return 1;
92+
}
93+
94+
for (i = 0; i < lsh_num_builtins(); i++){
95+
if(strcmp(args[0], builtin_str[i]) == 0){
96+
return (*builtin_func[i])(args);
97+
}
98+
}
99+
100+
return lsh_launch(args);
101+
}
102+
103+
/* Parse input to get the arguments */
104+
char **lsh_split_line(char *line){
105+
int bufsize = LSH_TOK_DELIM, position = 0;
106+
char **tokens = malloc(bufsize * sizeof(char*));
107+
char *token;
108+
109+
if(!tokens){
110+
fprintf(stderr, "lsh: allocation error\n");
111+
exit(EXIT_FAILURE);
112+
}
113+
114+
token = strtok(line, LSH_TOK_DELIM);
115+
while(token != NULL){
116+
tokens[position] = token;
117+
position++;
118+
119+
if(position >= bufsize){
120+
bufsize += LSH_TOK_BUFSIZE;
121+
tokens = realloc(tokens, bufsize * sizeof(char*));
122+
if(!tokens){
123+
fprintf(stderr, "lsh: allocation error\n");
124+
exit(EXIT_FAILURE);
125+
}
126+
}
127+
128+
token = strtok(NULL, LSH_TOK_DELIM);
129+
}
130+
tokens[position] = NULL;
131+
return tokens;
132+
}
133+
134+
/* Read input from stdin */
135+
char *lsh_read_line(void)
136+
{
137+
int bufsize = LSH_RL_BUFSIZE;
138+
int position = 0;
139+
char *buffer = malloc(sizeof(char) * bufsize);
140+
int c;
141+
142+
if(!buffer){
143+
fprintf(stderr, "lsh: allocation error\n");
144+
exit(EXIT_FAILURE);
145+
}
146+
147+
while(1){
148+
/* Read a character */
149+
c = getchar()
150+
151+
if(c == EOF || c == '\n'){
152+
buffer[position] = '\0';
153+
return buffer;
154+
}else{
155+
buffer[position] = c;
156+
}
157+
position++;
158+
159+
/* If buffer exceeded, reallocate buffer */
160+
if(position >= bufsize){
161+
bufsize += LSH_RL_BUFSIZE;
162+
buffer = realloc(buffer, bufsize);
163+
if(!buffer){
164+
fprintf(stderr, "lsh: allocation error\n");
165+
exit(EXIT_FAILURE);
166+
}
167+
}
168+
}
169+
}
170+
171+
/* Loop for getting input and executing it */
172+
void lsh_loop(void)
173+
{
174+
char *line;
175+
char **args;
176+
int status;
177+
178+
do {
179+
printf(">");
180+
line = lsh_read_line();
181+
args = lsh_split_line();
182+
status = lsh_execute(line);
183+
184+
free(line);
185+
free(args);
186+
} while(status);
187+
}
188+
189+
int main(void)
190+
{
191+
lsh_loop();
192+
193+
return EXIT_SUCCESS;
194+
}

0 commit comments

Comments
 (0)