89 lines
2.4 KiB
C++
89 lines
2.4 KiB
C++
#include <cstring>
|
|
#include <functional>
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
// WARNING: NO more headers allowed!
|
|
|
|
using std::function;
|
|
using std::map;
|
|
using std::pair;
|
|
using std::string;
|
|
using std::vector;
|
|
namespace final {
|
|
class arguments {
|
|
private:
|
|
// WARNING: You cannot add more member variables.
|
|
int _argc;
|
|
char **_argv;
|
|
|
|
public:
|
|
arguments() : _argc(0), _argv(nullptr) {}
|
|
explicit arguments(const string &cmd) {
|
|
// todo implement constructor
|
|
int first_pos = 0;
|
|
int length = cmd.length();
|
|
_argc = 0;
|
|
while (first_pos < length && cmd[first_pos] == ' ') first_pos++;
|
|
if (first_pos == length) {
|
|
_argv = new char *[1];
|
|
return;
|
|
}
|
|
std::vector<char *> argv_tmp;
|
|
for (int i = first_pos + 1; i < length; i++) {
|
|
if (cmd[i] != ' ') continue;
|
|
_argc++;
|
|
char *arg_tmp = new char[i - first_pos + 2];
|
|
std::memmove(arg_tmp, cmd.c_str() + first_pos, i - first_pos);
|
|
arg_tmp[i - first_pos] = '\0';
|
|
argv_tmp.push_back(arg_tmp);
|
|
first_pos = i + 1;
|
|
while (first_pos < length && cmd[first_pos] == ' ') first_pos++;
|
|
if (first_pos == length) break;
|
|
}
|
|
if (first_pos < length) {
|
|
_argc++;
|
|
char *arg_tmp = new char[length - first_pos + 2];
|
|
std::memmove(arg_tmp, cmd.c_str() + first_pos, length - first_pos);
|
|
arg_tmp[length - first_pos] = '\0';
|
|
argv_tmp.push_back(arg_tmp);
|
|
}
|
|
_argv = new char *[_argc];
|
|
for (int i = 0; i < _argc; i++) _argv[i] = argv_tmp[i];
|
|
// std::cerr << "argc: " << _argc << std::endl;
|
|
}
|
|
~arguments() {
|
|
// todo implement destructor
|
|
for (int i = 0; i < _argc; i++) delete[] _argv[i];
|
|
delete[] _argv;
|
|
}
|
|
// WARNING: You cannot modify the following functions
|
|
int argc() const { return _argc; }
|
|
char **argv() const { return _argv; }
|
|
};
|
|
|
|
// You don't need to modify shell.
|
|
class shell {
|
|
private:
|
|
map<int, arguments> running_list;
|
|
|
|
public:
|
|
shell() = default;
|
|
|
|
void run(int pid, const string &cmd,
|
|
const function<void(int, char **)> &invoked) {
|
|
running_list.emplace(pid, cmd);
|
|
invoked(running_list[pid].argc(), running_list[pid].argv());
|
|
}
|
|
|
|
int subprocessExit(int pid, int return_value) {
|
|
running_list.erase(pid);
|
|
return return_value;
|
|
}
|
|
vector<int> getRunningList() const {
|
|
vector<int> rt;
|
|
for (auto &pair : running_list) rt.push_back(pair.first);
|
|
return rt;
|
|
}
|
|
};
|
|
} // namespace final
|