-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathshell.c
171 lines (140 loc) · 2.68 KB
/
shell.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
162
163
164
165
166
167
168
169
170
171
/*Authors: Stephen Brikiatis and Kelly Morrissey
Class: CSI-385-01
Assignment: FAT12
Date Assigned: 08/30/16
Due Date: 11/2/16
Description: This code is the shell that will be used to call the commands in relation to the FAT12.
Certification of Authenticity:
We certify that this assignment is entirely our own work.
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#define BUFFER_SIZE 1024
#define TOKEN_BUFFER_SIZE 64
#define DELIMETER " \t\r\n\a"
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
extern void startSuperVars();
void runLoop();
char* readInput();
char** parseInput(char* line);
int executeCommand(char** cmd);
#define NUM_BUILT_INS 5
int main(int argc, char* argv[])
{
startSuperVars();
runLoop();
return 0;
}
void runLoop()
{
int status;
status = 1;
char* line;
char** args;
do
{
//1. prompt
printf("> ");
//2. read
line = readInput();
//3. parse
args = parseInput(line);
//4. execute
status = executeCommand(args);
//cleanup
free(line);
free(args);
} while(status == 1);
}
int executeCommand(char** cmd)
{
//Executes the basic shell commands
pid_t x;
int status = 1;
x = fork();
if(x == -1)
{
perror("fork error\n");
}
else if(x == 0)
{
//Process to execute commands
status = execvp(cmd[0], cmd);
_exit(0);
}
else if(x > 0)
{
//Code for the parent would go here if needed
}
pid_t y;
for(;;)
{
//will wait for all children created.
y = wait(NULL);
if(y == -1)
{
int num = errno;
if(num == ECHILD)
{
break;
//should do nothing but allow the program to continue
}
else if(num == EINTR)
{
printf("The process was interrupted");
break;
}
}
}
if((strncmp(cmd[0], "exit", 4) == 0 | strncmp(cmd[0], "logout", 6) == 0))
{
status = 0;
}
return status;
}
char* readInput()
{
//Reads the input from the console
char* line = NULL;
size_t bufferSize = 0;
getline(&line, &bufferSize, stdin);
return line;
}
char** parseInput(char* input)
{
//Parses the input to be able to execute commands
int bufferSize = TOKEN_BUFFER_SIZE;
int position = 0;
char** tokens = malloc(bufferSize * sizeof(char*));
char* token;
if(!tokens)
{
perror("malloc error\n");
exit(EXIT_FAILURE);
}
token = strtok(input, DELIMETER);
while(token != NULL)
{
tokens[position] = token;
position++;
if(position >= bufferSize)
{
bufferSize += TOKEN_BUFFER_SIZE;
tokens = realloc(tokens, bufferSize * sizeof(char*));
if(!tokens)
{
perror("realloc error\n");
exit(EXIT_FAILURE);
}
}
token = strtok(NULL, DELIMETER);
}
tokens[position] = NULL;
return tokens;
}