-
Notifications
You must be signed in to change notification settings - Fork 0
/
shell_swapnil.c
159 lines (149 loc) · 4.35 KB
/
shell_swapnil.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<readline/readline.h>
#include<readline/history.h>
/* Parsing given input to check if pipe exists */
int parsePipe(char* line, char *linepipe[2]){
for (int i = 0; i < 2; i++) {
linepipe[i] = strsep(&line, "|");
if (linepipe[i] == NULL)
break;
}
}
/* Parsing given input to check if semicolon (;) exists */
void parseSemic(char* line, char** argvs){
for (int i = 0; i < 64; i++) {
argvs[i] = strsep(&line, ";");
if (argvs[i] == NULL)
break;
if (strlen(argvs[i]) == 0)
i--;
}
}
/* Parsing given input to check if blank (;) exists */
void parseBlank(char* lines, char** argv)
{
for (int i = 0; i < 64; i++) {
argv[i] = strsep(&lines, " ");
if (argv[i] == NULL)
break;
if (strlen(argv[i]) == 0)
i--;
}
}
/* Execute the non pipe cmd
Checks if there is & trailing for background program
Replacing & with \0 (NULL)
If the & background exists don't wait for the chid to finish
If not background wait for child to finish*/
void execute(char **argv)
{
pid_t pid;
int background=0;
for (int i=0; i<64 ; i++){
if (argv[i]==NULL){
if(argv[i-1][strlen(argv[i-1])-1] == '&')
{
background = 1; // if & exixts
argv[i-1][strlen(argv[i-1])-1] = '\0';
}
break;
}
}
pid = fork(); // Fork new process
if(pid == 0 && background == 1) // Child process with background
{
setpgid(pid, 0); // creates a new process group leader pid
execvp(*argv, argv);
printf("Command not found\n");
exit(1);
}
else if(pid == 0 && background != 1) // child process without background
{
execvp(*argv, argv);
printf("Command not found\n");
exit(1);
}
else if(background != 1) //wait for child to finish if not a background process
{
wait(NULL);
}
}
/* Execute the pipe cmd
Creates two child process and uses dup2 to send STDOUT_FILENO from
cmd 1 to STDIN_FILENO of cmd 2 */
void executePipe(char **argv, char **argv2){
int pipefd[2];
pid_t pid;
pipe(pipefd);
if (pipe(pipefd) < 0) {perror("Pipe could not be initialized\n"); exit(1);}
if(fork() == 0){ // child 1
close(pipefd[0]); // close read end of pipe for the write operation
dup2(pipefd[1], 1); // 1 - STDOUT_FILENO
close(pipefd[1]);
execvp(*argv, argv);
perror("Command not found\n");
exit(1);
}
if(fork() == 0){ //child 2
close(pipefd[1]); // close write end of pipe for read operation
dup2(pipefd[0], 0); // 0 - STDIN_FILENO
close(pipefd[0]);
execvp(*argv2, argv2);
perror("Command not found\n");
exit(1);
}
close(pipefd[0]); //close pipe
close(pipefd[1]);
wait(NULL); //waiting for both childen process to end
wait(NULL);
}
/////// MAIN ///////
void main(void)
{
char *line;
char *lines;
char *argv[64];
char *argv2[64];
char *argvs[64];
char *linepiped[2];
int parsecheck;
while (1) {
line = readline("ENTS669> "); // Take input
add_history(line); // for using cursor for previous cmd
parsePipe(line,linepiped); // function to split pipe cmd
if (linepiped[1] == NULL){ // if pipe is not present
parseSemic(line,argvs); // function to split cmd at ;
/* Loops through the multiple cmds splitted by ; */
for(int i=0; i<64 ; i++){
if (argvs[i]==NULL)
break;
lines=argvs[i];
parseBlank(lines, argv); //function to parse blank spaces
if (*(void**)argv != NULL){
/* checks if cmd is cd or exit if not
it uses a function to use execvp */
if (strcmp(argv[0], "exit") == 0)
exit(0);
else if (strcmp(argv[0], "cd") ==0){
chdir(argv[1]);
}
else{
execute(argv);
}
}
memset(argv, 0, sizeof(argv)); //clear argv
}
}
// if pipe is present
else{
parseBlank(linepiped[0], argv); //function to parse blank spaces
parseBlank(linepiped[1], argv2); //function to parse blank spaces
executePipe(argv,argv2); //executing the pipe cmd
}
}
}