-
Notifications
You must be signed in to change notification settings - Fork 0
/
Commands.h
executable file
·124 lines (103 loc) · 2.86 KB
/
Commands.h
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
#ifndef SMASH_COMMAND_H_
#define SMASH_COMMAND_H_
#include <vector>
#include <iostream>
#include <cstdarg>
#include "CommandUtils.h"
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#define COMMAND_ARGS_MAX_LENGTH (200)
#define COMMAND_MAX_ARGS (20)
class Command
{
public:
int output_fd = -1;
int error_fd = -1;
int input_fd = -1;
int oldStdout;
int oldStderr;
int oldStdin;
int job_id = -1;
int pid = -1;
std::vector<std::string> cmd_v;
Command(const char *cmd_line)
{
std::string cmd_line_s = cmd_line;
CommandUtils::_removeBackgroundSign(cmd_line_s);
cmd_v = CommandUtils::_split(cmd_line_s);
// handle > redirection
std::string cmd_str = std::string(cmd_line);
for (const auto &c : cmd_v)
{
if (c == ">" || c == ">>")
{
// pop all the arguments after the redirection
while (cmd_v.back() != c)
{
cmd_v.pop_back();
}
cmd_v.pop_back();
}
}
if (cmd_str.find(">>") != std::string::npos)
{
std::string filename = cmd_str.substr(cmd_str.find(">>") + 3);
filename = filename.substr(0, filename.find_last_not_of(' ') + 1);
this->output_fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666);
}
else if (cmd_str.find('>') != std::string::npos)
{
std::string filename = cmd_str.substr(cmd_str.find('>') + 2);
filename = filename.substr(0, filename.find_last_not_of(' ') + 1);
this->output_fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
}
else
{
this->output_fd = -1;
}
}
virtual ~Command() = default;
virtual void execute() = 0;
void setIODescriptors();
void cleanup();
pid_t getPid()
{
return pid;
}
std::string getCommandName() const;
void printError(const std::string &error_msg) const
{
std::cerr << "smash error: " << cmd_v[0] << ": " << error_msg << std::endl;
}
// virtual void prepare();
// virtual void cleanup();
// TODO: Add your extra methods if needed
};
class PipeCommand : public Command
{
// TODO: Add your data members
public:
PipeCommand(const char *cmd_line, std::vector<Command *> commands, std::vector<bool> redirectErrVector);
std::vector<Command *> commands;
std::vector<bool> redirectErrVector;
virtual ~PipeCommand(){};
void execute() override;
};
class RedirectionCommand : public Command
{
// TODO: Add your data members
public:
explicit RedirectionCommand(const char *cmd_line);
virtual ~RedirectionCommand() {}
void execute() override;
};
class GetFileInfoCommand : public Command
{
public:
explicit GetFileInfoCommand(const char *cmd_line);
virtual ~GetFileInfoCommand() {}
void execute() override;
};
#endif // SMASH_COMMAND_H_