-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathourShell.c
161 lines (139 loc) · 4.98 KB
/
ourShell.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
160
161
/*
CMPE_382 Section 01 Project 1
Members:
Tanercan Altuntas
Ahmet Kaan Toprakcioglu
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
void* functionThread(void* arg){ // Take the arg from parameter then send the system function.
system(arg);
pthread_exit(NULL);
}
FILE* batchfile;
int main(int argc, char *argv[]){
char input[512];
char* inputptr;
inputptr=input;
if(argc<2){
// control command line input, if it is true, the program run with interactive mode.
printf("ahmet@tanercan:>");
fgets(inputptr,512,stdin);
}else{
// else statement intialize the batchfile. If fopen can not find the value what is batch file. Send error message then, the program continue with interactive mode.
batchfile= fopen(argv[1],"r");
if(!batchfile){
printf("%s\n",strerror(errno));
argc--;
printf("ahmet@tanercan:>");
fgets(inputptr,512,stdin);
}else{
fgets(input,512,batchfile);
}
}
int index;
int control;
int controlQuit;
while(strcmp(inputptr,"quit\n")!=0){
index=0;
control=1;
controlQuit=0;
while(input[index]!='\n'){
if(input[index]==';'){
control=0;
break;
}
index++;
}
if(control){
//this checks whether the statement input has a ";" character in it.
if(strstr(input,"|")){
char* tokenPipe = strtok(input, "|");
while(tokenPipe!=NULL){
system(tokenPipe);
tokenPipe=strtok(NULL,"|");
}
}else{
// else condition, the input is a single command to send it directly system function.
system(input);
}
}else{
//program run here. If input include ";" or ";|" characters.
pthread_t newthread;
if(strstr(input,"|")){
/*
This declaration checks if the input contains the pipe character. Separates inputs with a pipe character.
Then it separates the inputs separated by the pipe character with semicolon characters if they contain semicolon characters and sends them to the thread function.
*/
char* token2 = strtok(input, "|");
while(token2!=NULL){
if(strstr(token2,";")){
pthread_t newthread2;
char* seperate;
while((seperate=strsep(&token2,";"))!=NULL){
if(strstr(seperate,"quit")){
controlQuit=1;
}
else{
pthread_create(&newthread2, NULL, functionThread, (void *)seperate);
}
}
}else{
if(strstr(token2,"quit")){
controlQuit=1;
}else{
system(token2);
}
}
token2=strtok(NULL,"|");
}
}else{
/*
In this condition, the input contains only semicolon characters with input. Thus, it separates it with semicolon character and sends it to the thread function.
*/
char* token1 = strtok(input, ";");
while (token1 != NULL) {
if(strstr(token1,"quit")){
controlQuit=1;
}else{
pthread_create(&newthread,NULL,functionThread,(void *)token1);
}
token1 = strtok(NULL, ";");
}
}
sleep(1);
}
if(controlQuit){
/*
If this statement contains the word "quit" in any part of the input, it is not sent to the thread function.
First of all, the work must be done in the thread function.
*/
strcpy(inputptr,"quit\n");
}else{
//else statement define inputs according to some conditions.
if(argc<2){
//the user just ran the ourShellOutput file.
printf("ahmet@tanercan:>");
fgets(inputptr,512,stdin);
}else{
if(batchfile!=NULL){
//read lines from the batch file end of theese line, the file close.
if((fgets(input,512,batchfile))==NULL){
fclose(batchfile);
batchfile=NULL;
}
}
if(batchfile==NULL){
//If the batch file is closed, the program continues as interactive mode.
printf("ahmet@tanercan:>");
fgets(inputptr,512,stdin);
}
}
}
}
return 0;
}