-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshell.cpp
More file actions
123 lines (113 loc) · 4.62 KB
/
shell.cpp
File metadata and controls
123 lines (113 loc) · 4.62 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
122
123
#include "./Finder.h"
#include "./ParseCmd.h"
#include "./ShellCmd.h"
using namespace std;
int main()
{
// Opens history file to write/append to and initializes userCmd char pointer
ofstream shellHistory;
shellHistory.open("/home/kirbitz/Documents/CodingAssignments/CodingAssignment4/shellHistory.txt", ios::out | ios::app);
char *userCmd[25];
userCmd[0] = NULL;
int originalSTDIN, originalSTDOUT;
//Loops until user enters exit into terminal
while (userCmd[0] == NULL)
{
//Storing original STDOUT and STDIN file descriptors
originalSTDIN = dup(0);
originalSTDOUT = dup(1);
// Prints shell line and prompts user input
string userInput;
cout << "\033[1;35mmyshell@shell\033[0m:\033[1;31m";
ShellCmd::curDir(1);
cout << "\033[0m$ ";
getline(cin, userInput);
// Appends command to history
if (userInput.length() > 0)
shellHistory << userInput << endl;
// Tokenized vector of user inputs
vector<string> tokenizedInput = ParseCmd::getTokenVector(userInput);
vector<int> pipeRedirctPos = Finder::findSpecialToken(tokenizedInput);
// Runs loop to parse through commands based on pipe and redirect separation
for (int i = 0; i < pipeRedirctPos.size() - 2; i += 2)
{
//Set cmd to NULL then initializes command array with next user command
userCmd[0] = NULL;
ParseCmd::cStringCmd(tokenizedInput, userCmd, pipeRedirctPos[i], pipeRedirctPos[i + 2]);
//Breaks if user did not enter a command
if (userCmd[0] == NULL)
break;
// Checks if pipeRedirect found a pipe variable
if (pipeRedirctPos[i + 3] == 1)
{
//Spawns pipe for passing data through
int fds[2];
if (pipe(fds) < 0)
{
perror("Failed to create pipe");
}
ShellCmd::runChild(userCmd, fds);
dup2(fds[0], 0);
close(fds[0]);
dup2(originalSTDOUT, 1);
close(fds[1]);
}
// Checks if pipeRedirect found a indirect variable
else if (pipeRedirctPos[i + 3] == 2)
{
//Creates a file for reading data in from
int inFile;
if ((inFile = open(tokenizedInput[pipeRedirctPos[i + 2] + 1].c_str(), O_RDONLY, S_IRUSR)) < 0)
{
perror("Failed to open file");
}
//Checks if input should be redirected to an output
if (pipeRedirctPos[i + 5] == 3 && pipeRedirctPos[i + 4] != tokenizedInput.size())
{
//Creates a file for writing data out to
int outFile;
if ((outFile = open(tokenizedInput[pipeRedirctPos[i + 4] + 1].c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) < 0)
{
perror("Failed to open file");
}
//Runs child command with inFile and outFile
ShellCmd::runChild(userCmd, inFile, outFile);
i += 2;
}
else
//Runs child command with inFile and outFile data
ShellCmd::runChild(userCmd, inFile, false);
i+=2;
}
// Checks if pipeRedirect found a outdirect variable
else if (pipeRedirctPos[i + 3] == 3 && pipeRedirctPos[i + 2] != tokenizedInput.size())
{
//Creates a file for writing out data to
int file;
if ((file = open(tokenizedInput[pipeRedirctPos[i + 2] + 1].c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) < 0)
{
perror("Failed to open file");
}
//Runs the child command with the outfile and notifiying the command that it is receiving an outfile
ShellCmd::runChild(userCmd, file, true);
i += 2;
}
else
{
//Runs a standard command
ShellCmd::runChild(userCmd);
}
}
// Sets userCmd[0] to NULL so loop will not exit
userCmd[0] = NULL;
// Sets file descriptor of stdin and stdout back to default
dup2(originalSTDIN, 0);
dup2(originalSTDOUT, 1);
close(originalSTDIN);
close(originalSTDOUT);
fflush(stdout);
}
// Closes history file
shellHistory.close();
return 0;
}