-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSimple_Linux_Shell.c
More file actions
121 lines (107 loc) · 1.94 KB
/
Simple_Linux_Shell.c
File metadata and controls
121 lines (107 loc) · 1.94 KB
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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
char *reading_line()
{
char *input = NULL;
size_t temp = 0;
getline(&input,&temp,stdin);
return input;
}
char **split_line(char *line)
{
char *delim= " \t\n\r\a";
int num_words = 30,num=0;
char *token;
char **tokens = malloc(num_words*sizeof(char *));
if(!tokens)
fprintf(stderr,"memory allocation fail");
token = strtok(line,delim);
while(token != NULL)
{
tokens[num]= token;
num++;
if(num >= num_words)
{
num_words += num_words;
tokens = realloc(tokens,num_words*sizeof(char *));
if(!tokens)
fprintf(stderr,"memory reallocation fail");
}
token = strtok(NULL,delim);
}
tokens[num] = NULL;
return tokens;
}
char non_builtin(char **args)
{
pid_t pid = fork();
int status;
if(pid ==0)
{
if(execvp(args[0],args)!=0)
{
fprintf(stderr,"execution error");
exit(EXIT_FAILURE);
}
}
else if(pid <0)
fprintf(stderr,"fork error");
else
{
do
{
waitpid(pid,&status,WUNTRACED);
}while(!WIFEXITED(status)&&!WIFSIGNALED(status));
}
return !status;
}
int shell_cd(char **args);
int shell_exit(char **args);
int shell_cd(char **args)
{
if(args[1]==NULL)
fprintf(stderr,"expecting an argument after \"cd\"");
else
{
if(chdir(args[1])!=0)
perror("dir change error");
}
return 1;
}
int shell_exit(char **args)
{
return 0;
}
char *builtin_list[] = {"cd","exit"};
int (*builtin_func[])(char **args) = {&shell_cd,&shell_exit};
#define num_builtin (sizeof(builtin_list)/sizeof(char *))
int shell_execute(char **args)
{
if(args[0]==NULL)
return 1;
for(int i=0;i<num_builtin;i++)
{
if(strcmp(args[0],builtin_list[i])==0)
return (builtin_func[i])(args);
}
return non_builtin(args);
}
int main()
{
char *line;
char **args;
int status;
do
{
printf(">> ");
line = reading_line();
args = split_line(line);
status = shell_execute(args);
free(line);
free(args);
}while(status);
return 0;
}