Skip to content

Commit e1dc060

Browse files
authored
First and Final commit
0 parents  commit e1dc060

File tree

1 file changed

+344
-0
lines changed

1 file changed

+344
-0
lines changed

myShell.c

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <unistd.h>
5+
#include <sys/wait.h>
6+
#include <stdbool.h>
7+
#include <errno.h>
8+
9+
10+
void takeIn(char in[]){
11+
12+
fgets(in,512,stdin);
13+
14+
//exclude '\n' character (enter) from string-input
15+
int i = 0;
16+
while (in[i]!='\0'){
17+
i++;
18+
}
19+
in[i-1]='\0';
20+
}
21+
22+
23+
void parse(char input[], char* toks[],const char delimeter[]){
24+
//general parsing function
25+
char *token;
26+
int i=0;
27+
token = strtok(input, delimeter);
28+
29+
while( token != NULL ) {
30+
31+
toks[i]=token;
32+
i ++;
33+
token = strtok(NULL, delimeter);
34+
35+
}
36+
toks[i] = NULL;
37+
38+
}
39+
40+
41+
int seperateCommands(char input[],char *cmds[], bool* success){
42+
char *token;
43+
int i=0,pos=0;
44+
45+
//find all delimiters
46+
for(int j=0;j<strlen(input)-1;j++){
47+
if(input[j]=='&' && input[j+1]=='&'){
48+
success[pos]=true;
49+
pos++;
50+
}else if(input[j]==';'){
51+
success[pos]=false;
52+
pos++;
53+
}
54+
}
55+
56+
//split the commands
57+
58+
parse(input, cmds, ";&&"); //parse iput in ';' or '&&'
59+
60+
return pos+1; //pos+1 = number of commands
61+
}
62+
63+
64+
int executeCmd(char* tokens[]){
65+
int status;
66+
pid_t child_pid;
67+
68+
child_pid = fork();
69+
70+
if(child_pid == 0) {
71+
/*child process. */
72+
if (execvp(tokens[0], tokens)<0){
73+
perror(tokens[0]);
74+
return -1;
75+
}
76+
}else if(child_pid<0){
77+
perror("Fork failed");
78+
return 1;
79+
} else {
80+
waitpid(child_pid, &status, WUNTRACED);
81+
}
82+
if (status==0){
83+
return 0;
84+
}else{
85+
return -1;
86+
}
87+
}
88+
89+
int findPipe(char cmds[]){
90+
if(strchr(cmds, '|')!=NULL){
91+
return 1;
92+
}else{
93+
return 0;
94+
}
95+
}
96+
97+
int findRedirection(char cmds[]){
98+
99+
if(strchr(cmds, '>')!=NULL){
100+
return 1;
101+
}else if(strchr(cmds, '<')!=NULL){
102+
return 2;
103+
}else{
104+
return 0;
105+
}
106+
}
107+
108+
int executeRedirection(char cmds[], int f){
109+
110+
char *tokens1[512];
111+
char *tokens2[512];
112+
int status;
113+
pid_t child_pid;
114+
115+
parse(cmds, tokens1, "<>"); //parse in spaces or '<' or '>'
116+
117+
parse(tokens1[0], tokens2, " \t");
118+
119+
char *token= strtok(tokens1[1], " \t");
120+
121+
while( tokens1[1] == " \t") {
122+
123+
token = strtok(NULL, " \t");
124+
125+
}
126+
127+
char *fileName= token;
128+
129+
FILE* file = fopen(fileName, "a+");
130+
131+
child_pid = fork();
132+
133+
if(child_pid == 0) {
134+
/* This is done by the child process. */
135+
if(f==1){
136+
close(1); //close stdout
137+
dup2(fileno(file),fileno(stdout)); //stout goes to file
138+
139+
}else if(f==2){
140+
close(0); //close stdin
141+
dup2(fileno(file),fileno(stdin)); //stdin is in file
142+
}
143+
144+
if (execvp(tokens2[0], tokens2)<0){
145+
perror(tokens2[0]);
146+
exit(1);
147+
}
148+
}else if(child_pid<0){
149+
perror("Fork failed");
150+
dup2(fileno(file),fileno(stderr)); //stderr goes to file
151+
exit(1);
152+
} else {
153+
fclose(file);
154+
waitpid(child_pid, &status, WUNTRACED);
155+
}
156+
157+
if (status==0){
158+
return 0;
159+
}else{
160+
return -1;
161+
}
162+
163+
}
164+
165+
166+
167+
int executePipe(char cmds[]){
168+
int stat1, stat2; //process1 status1,process2 status2
169+
pid_t pid1, pid2;
170+
int fd[2];
171+
char *tokens1[512];
172+
char *tokens2[512];
173+
char *tokens3[512];
174+
175+
parse(cmds, tokens1, "|"); //tokens1 contains the cmds
176+
177+
// Create a pipe.
178+
if(pipe(fd) == -1){
179+
perror("Pipe failed");
180+
return -1;
181+
}
182+
183+
int r1,r2;
184+
r1=findRedirection(tokens1[0]);
185+
r2=findRedirection(tokens1[1]);
186+
187+
// Create our first process.
188+
pid1 = fork();
189+
if (pid1 < 0) {
190+
perror("Fork failed");
191+
exit(1);
192+
}else if (pid1 == 0) {
193+
dup2(fd[1], 1);
194+
close(fd[0]);
195+
if(r1==0){
196+
parse(tokens1[0], tokens2, " \t"); //tokens2 the 1st cmd(pefore pipe)
197+
execvp(tokens2[0], tokens2); // run command BEFORE pipe character in userinput
198+
perror("Execvp failed");
199+
exit(1);
200+
}else{
201+
executeRedirection(tokens1[0],r1);
202+
exit(0);
203+
}
204+
205+
}
206+
close(fd[1]);
207+
// Wait for everything to finish and exit.
208+
waitpid(pid1, &stat1, WUNTRACED);
209+
210+
// Create our second process.
211+
pid2 = fork();
212+
if (pid2 < 0) {
213+
perror("Fork failed");
214+
exit(1);
215+
}else if (pid2 == 0) {
216+
dup2(fd[0], 0);
217+
close(fd[1]);
218+
if(r2==0){
219+
parse(tokens1[1], tokens3, " \t"); //tokens3 the 2nd cmd(after pipe)
220+
execvp(tokens3[0], tokens3); // run command AFTER pipe character in userinput
221+
perror("Execvp failed");
222+
exit(1);
223+
}else{
224+
executeRedirection(tokens1[1],r2);
225+
exit(0);
226+
}
227+
}
228+
close(fd[0]);
229+
waitpid(pid2, &stat2, WUNTRACED);
230+
231+
232+
if (stat1==0 && stat2==0){
233+
return 0;
234+
}else{
235+
return -1;
236+
}
237+
238+
239+
}
240+
241+
void parseExec(char *input){
242+
243+
int redirectionFound=-10; //random non valid initialization
244+
int pipeFound=-10;
245+
int numOfCmds=0;
246+
char *cmds[512]; //commands stored seperately
247+
char *toks[512]; //parts of each command stored seperately
248+
bool *success=(bool *)malloc(512*sizeof(bool));
249+
//**********parse multiple commands**************
250+
numOfCmds = seperateCommands(input, cmds, success);
251+
//***********parse/execute each command**************************
252+
for (int i =0 ; i<numOfCmds; i++){
253+
//check for exit
254+
if(strcmp(cmds[i],"quit") == 0){
255+
exit(0);
256+
}
257+
258+
pipeFound=findPipe(cmds[i]);
259+
redirectionFound=findRedirection(cmds[i]);
260+
261+
if(pipeFound==0 && redirectionFound==0){
262+
//Neither pipe nor redirection found
263+
parse(cmds[i], toks, " \t"); //parse space
264+
if (executeCmd(toks)==-1 && success[i]==1){
265+
break;
266+
}
267+
268+
}else if(pipeFound==0 && (redirectionFound==1 || redirectionFound==2)){
269+
//Redirection only
270+
if (executeRedirection(cmds[i],redirectionFound)==-1 && success[i]==1){
271+
break;
272+
}
273+
}else{
274+
//pipe only
275+
if (executePipe(cmds[i])==-1 && success[i]==1){
276+
break;
277+
}
278+
}
279+
}
280+
281+
}
282+
283+
284+
void shell(){
285+
//user_aem
286+
printf("gonidelis_8794>");
287+
288+
//*************initiallization*****************
289+
char in[512]; //string-input from user
290+
291+
//***********take input from user****************
292+
takeIn(in);
293+
parseExec(in);
294+
shell();
295+
}
296+
297+
int batchfile_mode(char * argv[]){
298+
299+
char str[512];
300+
char *batch_cmds[512];
301+
int i=0, j=0;
302+
int n; //number of batchfile commands
303+
304+
FILE *fp;
305+
fp = fopen(argv[1], "r");
306+
307+
if(fp == NULL) {
308+
perror("Error opening file");
309+
return(-1);
310+
}
311+
312+
while(fgets(str,512, fp)!=NULL){
313+
batch_cmds[i] = strdup(str);
314+
i++;
315+
n = i;
316+
}
317+
318+
for (i=0;i<n;i++){
319+
320+
321+
batch_cmds[i] = strtok(batch_cmds[i], "\n");
322+
323+
parseExec(batch_cmds[i]);
324+
}
325+
326+
327+
fclose(fp);
328+
329+
return 0;
330+
}
331+
332+
333+
int main(int argc, char *argv[]){
334+
if (argc >=2){
335+
//batchfile mode
336+
batchfile_mode(argv);
337+
338+
}else{
339+
//interactive mode
340+
shell(); //shell() called recursively
341+
}
342+
343+
return 0;
344+
}

0 commit comments

Comments
 (0)