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.
 
 
 

113 lines
2.4 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. class Child {
  50. public:
  51. enum class LogicOp { NONE=0, OR, AND };
  52. using command_t = std::vector<std::string>;
  53. using Error = std::runtime_error;
  54. public:
  55. ~Child ();
  56. Child () noexcept = default;
  57. Child (const command_t& c) : command{c} { }
  58. Child (command_t&& c) : command{std::move(c)} { }
  59. Child& make_arguments ();
  60. bool execute ();
  61. private:
  62. void redirect_std_if(std::string fn, fd_t std_fd);
  63. void restore_std_if(fd_t std_fd);
  64. private:
  65. command_t command {};
  66. ArgList arguments {};
  67. fd_t files[3] = {-1, -1, -1};
  68. fd_t sstd [3] = {-1, -1, -1};
  69. std::string filenames[3] = {"", "", ""};
  70. LogicOp logic {LogicOp::NONE};
  71. bool pipe {false};
  72. };
  73. class Sequencer {
  74. public:
  75. Sequencer& parse (const std::string& input);
  76. Sequencer& execute ();
  77. private:
  78. bool is_seperator (std::string& s) {
  79. return (s == "&&" || s == "||") ? true : false;
  80. }
  81. bool is_pipe (std::string& s) {
  82. return (s == "|") ? true : false;
  83. }
  84. private:
  85. std::vector <
  86. std::vector <Child>
  87. > seq_ {};
  88. };
  89. }
  90. #endif /* __sequencer_h__ */