|
@@ -35,6 +35,28 @@ namespace snel { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::string filter (const std::string in) { |
|
|
|
|
|
std::string out; |
|
|
|
|
|
char prev {0}, cur, next {0}; |
|
|
|
|
|
|
|
|
|
|
|
for (auto i = in.begin(); i != in.end() ; ++i) { |
|
|
|
|
|
cur = *i; |
|
|
|
|
|
if (cur == '|') { |
|
|
|
|
|
if (prev != ' ') out += ' '; |
|
|
|
|
|
next = *++i; |
|
|
|
|
|
if (next == '|' || next == ' ') { |
|
|
|
|
|
out += cur; cur = next; // syntax ok |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
// syntax problem, insert a space |
|
|
|
|
|
out += cur; out += ' '; cur = next; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
prev = cur; |
|
|
|
|
|
out += cur; |
|
|
|
|
|
} |
|
|
|
|
|
return out; |
|
|
|
|
|
} |
|
|
/* |
|
|
/* |
|
|
* ========== ArgList ========== |
|
|
* ========== ArgList ========== |
|
|
*/ |
|
|
*/ |
|
@@ -44,7 +66,7 @@ namespace snel { |
|
|
delete[] p; |
|
|
delete[] p; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
ArgList& ArgList::push_back(const std::basic_string<type>& item) { |
|
|
|
|
|
|
|
|
ArgList& ArgList::push_back(const std::string& item) { |
|
|
vtype it = new type[item.length()+1]; |
|
|
vtype it = new type[item.length()+1]; |
|
|
|
|
|
|
|
|
// get data |
|
|
// get data |
|
@@ -92,7 +114,7 @@ namespace snel { |
|
|
} |
|
|
} |
|
|
Child& Child::make_arguments () { |
|
|
Child& Child::make_arguments () { |
|
|
bool in{false}, out{false}, err{false}; |
|
|
bool in{false}, out{false}, err{false}; |
|
|
bool CanRedirectIn = (pipe_.from) ? true : false; |
|
|
|
|
|
|
|
|
bool CanRedirectIn = (!pipe_.from) ? true : false; |
|
|
bool CanRedirectOut = (!pipe_.to) ? true : false; |
|
|
bool CanRedirectOut = (!pipe_.to) ? true : false; |
|
|
|
|
|
|
|
|
for (auto& t: command) { |
|
|
for (auto& t: command) { |
|
@@ -132,8 +154,10 @@ namespace snel { |
|
|
return *this; |
|
|
return *this; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Child::execute(const Child* previous) { |
|
|
|
|
|
|
|
|
bool Child::execute(std::vector<Child>::iterator it, bool first) { |
|
|
bool stop = {false}; |
|
|
bool stop = {false}; |
|
|
|
|
|
if (!first) --it; |
|
|
|
|
|
Child& previous = *it; |
|
|
|
|
|
|
|
|
// Check parent redirection |
|
|
// Check parent redirection |
|
|
redirect_std_if (filenames[STDIN_], STDIN_); |
|
|
redirect_std_if (filenames[STDIN_], STDIN_); |
|
@@ -156,10 +180,9 @@ namespace snel { |
|
|
if ((dup2(pipe_.fd[1], STDOUT_)) == -1) // redirect output |
|
|
if ((dup2(pipe_.fd[1], STDOUT_)) == -1) // redirect output |
|
|
throw Error("Child pipe[to]: Can not redirect through pipe"); |
|
|
throw Error("Child pipe[to]: Can not redirect through pipe"); |
|
|
} |
|
|
} |
|
|
else if ((previous!= nullptr) && pipe_.from) { // receiveing child |
|
|
|
|
|
std::cout << "from[0]=" << previous->pipe().fd[0] << " from[1]=" << previous->pipe().fd[1]<< std::endl; |
|
|
|
|
|
close (previous->pipe().fd[1]); // close the write end |
|
|
|
|
|
if ((dup2(previous->pipe().fd[0], STDIN_)) == -1) // redirect input |
|
|
|
|
|
|
|
|
else if (!first && pipe_.from) { // receiveing child |
|
|
|
|
|
close (previous.pipe().fd[1]); // close the write end |
|
|
|
|
|
if ((dup2(previous.pipe().fd[0], STDIN_)) == -1) // redirect input |
|
|
throw Error("Child pipe[from]: Can not redirect through pipe"); |
|
|
throw Error("Child pipe[from]: Can not redirect through pipe"); |
|
|
} |
|
|
} |
|
|
execvp(arguments.front(), arguments.data()); |
|
|
execvp(arguments.front(), arguments.data()); |
|
@@ -169,7 +192,8 @@ namespace snel { |
|
|
} |
|
|
} |
|
|
else { // parent |
|
|
else { // parent |
|
|
if (pipe_.to) close (pipe_.fd[1]); |
|
|
if (pipe_.to) close (pipe_.fd[1]); |
|
|
else if (pipe_.from) close (previous->pipe().fd[0]); |
|
|
|
|
|
|
|
|
else if (!first && pipe_.from) |
|
|
|
|
|
close (previous.pipe().fd[0]); |
|
|
|
|
|
|
|
|
int exit_status; |
|
|
int exit_status; |
|
|
waitpid(pid, &exit_status, 0); // wait child process to finish |
|
|
waitpid(pid, &exit_status, 0); // wait child process to finish |
|
@@ -233,14 +257,16 @@ namespace snel { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Sequencer& Sequencer::execute() { |
|
|
Sequencer& Sequencer::execute() { |
|
|
for (auto& batch : seq_) |
|
|
|
|
|
|
|
|
for (auto& batch : seq_) { |
|
|
|
|
|
bool first; |
|
|
|
|
|
first = true; |
|
|
for (auto it = batch.begin() ; it != batch.end(); ++it) { |
|
|
for (auto it = batch.begin() ; it != batch.end(); ++it) { |
|
|
Child& command = *it; |
|
|
Child& command = *it; |
|
|
Child p = (it != batch.begin()) ? std::prev(it) : Child{}; |
|
|
|
|
|
if (command.make_arguments().execute(p)) |
|
|
|
|
|
|
|
|
if (command.make_arguments().execute(it, first)) |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
first = false; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
seq_.clear(); |
|
|
seq_.clear(); |
|
|
return *this; |
|
|
return *this; |
|
|
} |
|
|
} |
|
|