A quick and dirty shell implementation for A.U.TH. (Operating systems Lab)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

121 lines
2.6 KiB

  1. /*
  2. * child.h
  3. *
  4. * Created on: Feb 11, 2019
  5. * Author: hoo2
  6. */
  7. #ifndef __sequencer_h__
  8. #define __sequencer_h__
  9. #include <exception>
  10. #include <string>
  11. #include <iostream>
  12. #include <sstream>
  13. #include <fstream>
  14. #include <vector>
  15. #include <utility>
  16. #include <algorithm>
  17. #include <unistd.h>
  18. #include <fcntl.h>
  19. #include <sys/wait.h>
  20. namespace snel {
  21. //! file descriptor type
  22. using fd_t = int;
  23. constexpr fd_t STDIN_ = STDIN_FILENO;
  24. constexpr fd_t STDOUT_ = STDOUT_FILENO;
  25. constexpr fd_t STDERR_ = STDERR_FILENO;
  26. std::string filter (const std::string in);
  27. /*!
  28. *
  29. */
  30. struct ArgList {
  31. using type = typename std::string::value_type; // Basic data type
  32. using vtype = type*; // Vector type
  33. using vtype_ptr = vtype*; // Pointer to vector type
  34. ~ArgList();
  35. ArgList() = default;
  36. ArgList(const ArgList&) = default;
  37. ArgList(ArgList&&) = default;
  38. ArgList& push_back(const std::string& item);
  39. vtype front () { return args_.front(); }
  40. size_t size () { return args_.size(); }
  41. vtype_ptr data() noexcept {
  42. return args_.data();
  43. }
  44. vtype_ptr operator*() noexcept {
  45. return data();
  46. }
  47. private:
  48. std::vector<vtype> args_ {nullptr};
  49. };
  50. struct Pipe {
  51. fd_t fd[2] {-1, -1};
  52. bool from {false};
  53. bool to {false};
  54. };
  55. class Child {
  56. public:
  57. enum class LogicOp { NONE=0, OR, AND };
  58. using command_t = std::vector<std::string>;
  59. using Error = std::runtime_error;
  60. public:
  61. ~Child ();
  62. Child () = default;
  63. Child (const command_t& c) : command{c} { }
  64. Child (command_t&& c) : command{std::move(c)} { }
  65. Child& make_arguments ();
  66. bool execute(std::vector<Child>::iterator it, bool first);
  67. Pipe& pipe() { return pipe_; }
  68. private:
  69. void redirect_std_if(std::string fn, fd_t std_fd);
  70. void restore_std_if(fd_t std_fd);
  71. private:
  72. command_t command {};
  73. ArgList arguments {};
  74. fd_t files[3] = {-1, -1, -1};
  75. fd_t sstd [3] = {-1, -1, -1};
  76. std::string filenames[3] = {"", "", ""};
  77. LogicOp logic {LogicOp::NONE};
  78. Pipe pipe_;
  79. };
  80. class Sequencer {
  81. public:
  82. Sequencer& parse (const std::string& input);
  83. Sequencer& execute ();
  84. private:
  85. bool is_seperator (std::string& s) {
  86. return (s == "&&" || s == "||" || s == "|") ? true : false;
  87. }
  88. bool is_pipe (std::string& s) {
  89. return (s == "|") ? true : false;
  90. }
  91. private:
  92. std::vector <
  93. std::vector <Child>
  94. > seq_ {};
  95. };
  96. }
  97. #endif /* __sequencer_h__ */