-
Notifications
You must be signed in to change notification settings - Fork 0
/
mysh.c
155 lines (137 loc) · 3.5 KB
/
mysh.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
/**
* @file mysh.c
* My implementation of a shell
*
* @author Brooks Beverstock
*/
#include "mysh.h"
int lengthArgs = 100;
int sizeArgs = 10;
string args[10];// can't use sizeArgs because of error.
pid_t pid = 1;
int status;
int new_stdout;
boolean redirStdIn = 0;
boolean redirStdOut = 0;
boolean redirStdError = 0;
boolean background = 0;
int main(int argc, char **argv)
{
// initialize variables
string promt = "mysh$ ";
string envPromt = getenv("MYPS");
string home = getenv("HOME");
boolean run = 1;
int sizeInput = 256;
int index = 0;
string input = malloc(sizeof(char*)*sizeInput);
string filename = malloc(20);
for(index = 0; index < sizeArgs; index++) {
args[index] = malloc(sizeof(char*)*sizeInput);
}
if(envPromt != NULL) { // user prompt
promt = envPromt;
}
while (run)
{
fprintf(stdout, "%s", promt);
getline(&input, (size_t *) &sizeInput, stdin);// please the compiler
//Tokenize user input
args[0] = strtok(input, " \n");// " \n" at the delimiters
for(index = 1; index < sizeArgs; index++) {
args[index] = strtok(NULL, " \n");
}
// //Debugging
// for(index = 0; index < 3; index++) {
// fprintf(stdout, "%s\n", args[index]);
// }
//main shell loop
if(args[0] != NULL)
{
// sets variable to run in background
for(index = 0; index < sizeArgs; ++index) {
if(args[index] != NULL && strcmp(args[index], "&")) {
background = 1;
}
}
// redirection set
for(index = 0; index < sizeArgs; index++) {
if(args[index] != NULL) {
switch(args[index][0])
{
case '<': redirStdIn = index;
break;
case '>': redirStdOut = index;
break;
case '2':
if(args[index][1] == '>') {
redirStdError = index;
}
break;
}
}
}
//if input is exit stop program
if(strcmp(args[0], "quit") == 0) {
run = 0;
}
// if cd is followed by a path move to the path else go to home.
//TODO check path
else if(strcmp(args[0], "cd") == 0) {
if(args[1] != NULL) {
chdir(args[1]);
} else {
chdir(home);
}
}
// used to test cd debug prints current working dir
else if(strcmp(args[0], "cwd") == 0) {
getcwd(input, sizeInput);
fprintf(stdout, "%s\n", input);
} else {
if(redirStdOut) // User cmd-line has >file in it
{
// Open file whose name begins with the _second_ character in cmd_args[i]
// for writing (create it if necessary), truncate the file to size 0,
// and give it user-group-other permissions of rw-r--r--
new_stdout = open(&(args[redirStdOut][1]), O_WRONLY|O_CREAT|O_TRUNC, (mode_t)0644);
if(new_stdout == -1) {
// Open failed: error-handling here
}
}
fprintf(stdout, "\n");
pid = vfork();
if(background == 0) {
wait(&status);
}
}
}
if(pid == 0) {//TODO need to pharse args to remove redirection, and background.
//sleep(2);
if(redirStdOut) {
if(dup2(new_stdout, 1) == -1) { // Put new_stdout on file desc #1
perror(user_argv[0]);
_exit(127);
}
close(new_stdout);
}
if(execvp(args[0], args) == -1) {
_exit(1);
}
}
if(redirStdIn) {
close(new_stdout);
redirStdIn = 0;
} else if(redirStdOut) {
close(new_stdout);
redirStdOut = 0;
}
redirStdError = 0;
background = 0;
}
for(index = 0; index < sizeArgs; ++index) {
free(args[index]);
}
free(input);
return 0;
}