119 lines
2.5 KiB
C++
Executable File
119 lines
2.5 KiB
C++
Executable File
/*
|
|
* child.h
|
|
*
|
|
* Created on: Feb 11, 2019
|
|
* Author: hoo2
|
|
*/
|
|
|
|
#ifndef __sequencer_h__
|
|
#define __sequencer_h__
|
|
|
|
#include <exception>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <vector>
|
|
#include <utility>
|
|
#include <algorithm>
|
|
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/wait.h>
|
|
|
|
|
|
namespace snel {
|
|
|
|
//! file descriptor type
|
|
using fd_t = int;
|
|
|
|
constexpr fd_t STDIN_ = STDIN_FILENO;
|
|
constexpr fd_t STDOUT_ = STDOUT_FILENO;
|
|
constexpr fd_t STDERR_ = STDERR_FILENO;
|
|
|
|
/*!
|
|
*
|
|
*/
|
|
struct ArgList {
|
|
using type = char; // Basic data type
|
|
using vtype = type*; // Vector type
|
|
using vtype_ptr = vtype*; // Pointer to vector type
|
|
|
|
~ArgList();
|
|
ArgList() = default;
|
|
ArgList(const ArgList&) = default;
|
|
ArgList(ArgList&&) = default;
|
|
|
|
ArgList& push_back(const std::basic_string<type>& item);
|
|
vtype front () { return args_.front(); }
|
|
size_t size () { return args_.size(); }
|
|
|
|
vtype_ptr data() noexcept {
|
|
return args_.data();
|
|
}
|
|
vtype_ptr operator*() noexcept {
|
|
return data();
|
|
}
|
|
private:
|
|
std::vector<vtype> args_ {nullptr};
|
|
};
|
|
|
|
|
|
struct Pipe {
|
|
fd_t fd[2] {-1, -1};
|
|
bool from {false};
|
|
bool to {false};
|
|
};
|
|
|
|
class Child {
|
|
public:
|
|
enum class LogicOp { NONE=0, OR, AND };
|
|
using command_t = std::vector<std::string>;
|
|
using Error = std::runtime_error;
|
|
|
|
public:
|
|
~Child ();
|
|
Child () noexcept = default;
|
|
Child (const command_t& c) : command{c} { }
|
|
Child (command_t&& c) : command{std::move(c)} { }
|
|
|
|
Child& make_arguments ();
|
|
bool execute (const Child* previous);
|
|
Pipe& pipe() { return pipe_; }
|
|
private:
|
|
void redirect_std_if(std::string fn, fd_t std_fd);
|
|
void restore_std_if(fd_t std_fd);
|
|
private:
|
|
command_t command {};
|
|
ArgList arguments {};
|
|
|
|
fd_t files[3] = {-1, -1, -1};
|
|
fd_t sstd [3] = {-1, -1, -1};
|
|
std::string filenames[3] = {"", "", ""};
|
|
LogicOp logic {LogicOp::NONE};
|
|
Pipe pipe_;
|
|
};
|
|
|
|
class Sequencer {
|
|
public:
|
|
Sequencer& parse (const std::string& input);
|
|
Sequencer& execute ();
|
|
|
|
private:
|
|
bool is_seperator (std::string& s) {
|
|
return (s == "&&" || s == "||" || s == "|") ? true : false;
|
|
}
|
|
bool is_pipe (std::string& s) {
|
|
return (s == "|") ? true : false;
|
|
}
|
|
|
|
private:
|
|
std::vector <
|
|
std::vector <Child>
|
|
> seq_ {};
|
|
};
|
|
|
|
}
|
|
|
|
#endif /* __sequencer_h__ */
|