-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path32197572_myshell.c
131 lines (110 loc) · 2.93 KB
/
32197572_myshell.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
/**
* myshell_execvp.c : Simple file view command
* @author : Nahyeon Jeon
* @email : [email protected]
* @version : 1.0
* @date : 2022.12.09
**/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
void help() {
printf("/***************Simple Shell***************/\n");
printf("You can use it just as the conventional shell\n\n");
printf("Some examples of the built-in commands\n");
printf("exit\t: exit this shell\n");
printf("help\t: show this help\n");
printf("&\t: background processing\n");
printf(">\t: redirection\n");
printf("/*****************************************/\n");
}
int tokenize(char* buf, char* delims, char* tokens[], int maxTokens) {
int token_count = 0;
char* token;
token = strtok(buf, delims);
while(token != NULL && token_count < maxTokens) {
tokens[token_count] = token;
token_count++;
token = strtok(NULL, delims);
}
// parshing
tokens[token_count] = NULL;
return token_count;
}
bool run(char* line) {
int i;
int fd;
int re = 0;
int bg = 0;
int re_check = 0;
int bg_check = 0;
int token_count;
pid_t child;
char delims[] = " \r\t\n";
char* tokens[128];
token_count = tokenize(line, delims, tokens, sizeof(tokens)/sizeof(char*));
if(token_count == 0) //아무런 입력이 없을 경우
return true;
// tokens[0]에 위치한 문자열과 exit를 서로 비교하여 두 문자열이 같다면 false를 반환
if(strcmp(tokens[0], "exit") == 0) // 터미널에 exit를 입력하면 shell을 종료한다.
return false;
// tokens[0]에 위치한 문자열과 help를 서로 비교하여 두 문자열이 같다면 help()함수를 호출
if(strcmp(tokens[0], "help") == 0){ // 터미널에 help를 입력하면 화면에 도움말이 출력된다.
help();
return true;
}
// handling redirection, pipe and background processing
//Background Processing과 Redirection을 해야 하는지 검사
for(i = 0; i < token_count; i++) {
if(strcmp(tokens[i],">") == 0) {
re = i;
re_check = 1;
break;
}
if(strcmp(tokens[i],"&") == 0) {
bg = i;
bg_check = 1;
break;
}
}
child = fork();
if(child < 0) { //fork error
printf("fork error\n");
return false;
}
else if(child == 0) { //Child Task
if(bg_check) {
tokens[bg] = '\0';
}
if(re_check == 1) {// > 입력시 출력 재지정
fd = open(tokens[re + 1], O_WRONLY|O_TRUNC|O_CREAT, 0664);
close(STDOUT_FILENO);
dup2(fd, STDOUT_FILENO);
tokens[re] = '\0';
}
execvp(tokens[0], tokens);
printf("execvp error\n"); //이 문장 출력시 execvp가 제대로 안됨
return false;
}
else if(bg_check == false) {
wait(NULL);
}
return true;
}
int main() {
char line[1024];
while(1) {
printf("%d $ ", get_current_dir_name());
fgets(line, sizeof(line) - 1, stdin);
if(run(line) == false)
break;
}
return 0;
}