1 /* 2 ** Copyright 2012-2013,2019-2021 Centreon 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 ** 16 ** For more information : contact@centreon.com 17 */ 18 19 #ifndef CC_PROCESS_POSIX_HH 20 #define CC_PROCESS_POSIX_HH 21 22 #include <sys/types.h> 23 #include <array> 24 #include <atomic> 25 #include <condition_variable> 26 #include <csignal> 27 #include <mutex> 28 #include <string> 29 #include "com/centreon/timestamp.hh" 30 31 CC_BEGIN() 32 33 class process_listener; 34 class process_manager; 35 36 /** 37 * @class process process_posix.hh "com/centreon/process_posix.hh" 38 * @brief Process execution class. 39 * 40 * Execute external process. 41 */ 42 class process { 43 friend class process_manager; 44 45 /* Constants */ 46 const std::array<bool, 3> _enable_stream; 47 process_listener* const _listener; 48 49 /* Constants except during exec() call */ 50 uint32_t _timeout; 51 52 /* Constants except when they are initialized at exec() and closed when 53 * process is over. */ 54 std::atomic_bool _is_timeout; 55 std::atomic_int _status; 56 std::array<int, 3> _stream; 57 pid_t _process; 58 59 /* Almost never changed, we have two such functions, one with pgid and the 60 * other without. */ 61 pid_t (*_create_process)(char**, char**); 62 63 public: 64 enum status { normal = 0, crash = 1, timeout = 2 }; 65 enum stream { in = 0, out = 1, err = 2 }; 66 67 private: 68 /* Error buffer: 69 * * cleared by exec(), 70 * * content get and then cleared by read_err() 71 * * and filled by do_read() when an error in the process occures. This last 72 * method is called by the process manager in its main loop when needed. 73 */ 74 std::string _buffer_err; 75 76 /* Output buffer: 77 * * cleared by exec(), 78 * * content get and then cleared by read() 79 * * and filled by do_read() when an output in the process occures. This last 80 * method is called by the process manager in its main loop when needed. 81 */ 82 std::string _buffer_out; 83 mutable std::condition_variable _cv_buffer_err; 84 mutable std::condition_variable _cv_buffer_out; 85 mutable std::condition_variable _cv_process_running; 86 timestamp _end_time; 87 mutable std::mutex _lock_process; 88 timestamp _start_time; 89 90 static void _close(int& fd) noexcept; 91 static pid_t _create_process_with_setpgid(char** args, char** env); 92 static pid_t _create_process_without_setpgid(char** args, char** env); 93 static void _dev_null(int fd, int flags); 94 static int _dup(int oldfd); 95 static void _dup2(int oldfd, int newfd); 96 bool _is_running() const noexcept; 97 void _kill(int sig); 98 static void _pipe(int fds[2]); 99 ssize_t do_read(int fd); 100 void do_close(int fd); 101 static void _set_cloexec(int fd); 102 103 public: 104 process(process_listener* l = nullptr, 105 bool in_stream = true, 106 bool out_stream = true, 107 bool err_stream = true); 108 virtual ~process() noexcept; 109 process(const process&) = delete; 110 process& operator=(const process&) = delete; 111 // void enable_stream(stream s, bool enable); 112 timestamp const& end_time() const noexcept; 113 void exec(char const* cmd, char** env = nullptr, uint32_t timeout = 0); 114 void exec(std::string const& cmd, uint32_t timeout = 0); 115 int exit_code() const noexcept; 116 status exit_status() const noexcept; 117 void kill(int sig = SIGKILL); 118 void read(std::string& data); 119 void read_err(std::string& data); 120 void setpgid_on_exec(bool enable) noexcept; 121 bool setpgid_on_exec() const noexcept; 122 timestamp const& start_time() const noexcept; 123 void terminate(); 124 void wait() const; 125 bool wait(uint32_t timeout) const; 126 uint32_t write(std::string const& data); 127 uint32_t write(void const* data, uint32_t size); 128 void update_ending_process(int status); 129 void set_timeout(bool timeout); 130 }; 131 132 CC_END() 133 134 #endif // !CC_PROCESS_POSIX_HH 135