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.
 
 
 

119 lines
2.5 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. /*!
  27. *
  28. */
  29. struct ArgList {
  30. using type = char; // Basic data type
  31. using vtype = type*; // Vector type
  32. using vtype_ptr = vtype*; // Pointer to vector type
  33. ~ArgList();
  34. ArgList() = default;
  35. ArgList(const ArgList&) = default;
  36. ArgList(ArgList&&) = default;
  37. ArgList& push_back(const std::basic_string<type>& item);
  38. vtype front () { return args_.front(); }
  39. size_t size () { return args_.size(); }
  40. vtype_ptr data() noexcept {
  41. return args_.data();
  42. }
  43. vtype_ptr operator*() noexcept {
  44. return data();
  45. }
  46. private:
  47. std::vector<vtype> args_ {nullptr};
  48. };
  49. struct Pipe {
  50. fd_t fd[2] {-1, -1};
  51. bool from {false};
  52. bool to {false};
  53. };
  54. class Child {
  55. public:
  56. enum class LogicOp { NONE=0, OR, AND };
  57. using command_t = std::vector<std::string>;
  58. using Error = std::runtime_error;
  59. public:
  60. ~Child ();
  61. Child () noexcept = default;
  62. Child (const command_t& c) : command{c} { }
  63. Child (command_t&& c) : command{std::move(c)} { }
  64. Child& make_arguments ();
  65. bool execute (const Child* previous);
  66. Pipe& pipe() { return pipe_; }
  67. private:
  68. void redirect_std_if(std::string fn, fd_t std_fd);
  69. void restore_std_if(fd_t std_fd);
  70. private:
  71. command_t command {};
  72. ArgList arguments {};
  73. fd_t files[3] = {-1, -1, -1};
  74. fd_t sstd [3] = {-1, -1, -1};
  75. std::string filenames[3] = {"", "", ""};
  76. LogicOp logic {LogicOp::NONE};
  77. Pipe pipe_;
  78. };
  79. class Sequencer {
  80. public:
  81. Sequencer& parse (const std::string& input);
  82. Sequencer& execute ();
  83. private:
  84. bool is_seperator (std::string& s) {
  85. return (s == "&&" || s == "||" || s == "|") ? true : false;
  86. }
  87. bool is_pipe (std::string& s) {
  88. return (s == "|") ? true : false;
  89. }
  90. private:
  91. std::vector <
  92. std::vector <Child>
  93. > seq_ {};
  94. };
  95. }
  96. #endif /* __sequencer_h__ */