1 /* 2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/> 3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com> 4 * 5 * This file is part of lsp-plugins 6 * Created on: 24 июл. 2019 г. 7 * 8 * lsp-plugins is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * any later version. 12 * 13 * lsp-plugins is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22 #ifndef CORE_IPC_PROCESS_H_ 23 #define CORE_IPC_PROCESS_H_ 24 25 #include <common/types.h> 26 #include <unistd.h> 27 #include <data/cvector.h> 28 #include <core/LSPString.h> 29 #include <core/io/IInStream.h> 30 #include <core/io/IOutStream.h> 31 32 namespace lsp 33 { 34 namespace ipc 35 { 36 /** 37 * Class for running processes 38 */ 39 class Process 40 { 41 public: 42 enum pstatus_t { 43 PSTATUS_CREATED, 44 PSTATUS_RUNNING, 45 PSTATUS_EXITED, 46 PSTATUS_ERROR 47 }; 48 49 private: 50 Process & operator = (const Process &); 51 52 typedef struct envvar_t { 53 LSPString name; 54 LSPString value; 55 } envvar_t; 56 57 private: 58 LSPString sCommand; 59 cvector<LSPString> vArgs; 60 cvector<envvar_t> vEnv; 61 pstatus_t nStatus; 62 int nExitCode; 63 64 #ifdef PLATFORM_WINDOWS 65 HANDLE hProcess; 66 WORD nPID; 67 HANDLE hStdIn; 68 HANDLE hStdOut; 69 HANDLE hStdErr; 70 #else 71 pid_t nPID; 72 int hStdIn; 73 int hStdOut; 74 int hStdErr; 75 #endif /* PLATFORM_WINDOWS */ 76 77 io::IOutStream *pStdIn; 78 io::IInStream *pStdOut; 79 io::IInStream *pStdErr; 80 81 protected: 82 static void destroy_args(cvector<LSPString> *args); 83 static void destroy_env(cvector<envvar_t> *env); 84 void close_handles(); 85 86 #ifdef PLATFORM_WINDOWS 87 static status_t append_arg_escaped(LSPString *dst, const LSPString *value); 88 status_t build_argv(LSPString *dst); 89 status_t build_envp(LSPString *dst); 90 #else 91 status_t build_argv(cvector<char> *dst); 92 status_t build_envp(cvector<char> *dst); 93 status_t spawn_process(const char *cmd, char * const *argv, char * const *envp); 94 status_t vfork_process(const char *cmd, char * const *argv, char * const *envp); 95 status_t fork_process(const char *cmd, char * const *argv, char * const *envp); 96 void execve_process(const char *cmd, char * const *argv, char * const *envp, bool soft_exit); 97 #endif /* PLATFORM_WINDOWS */ 98 99 public: 100 explicit Process(); 101 ~Process(); 102 103 public: 104 /** 105 * Set command for execution 106 * @param cmd command to execute 107 * @return status of operation 108 */ 109 status_t set_command(const LSPString *cmd); 110 111 /** 112 * Set command for execution 113 * @param cmd command to execute in UTF-8 encoding 114 * @return status of operation 115 */ 116 status_t set_command(const char *cmd); 117 118 public: 119 /** 120 * Get overall number of additional command-line arguments 121 * @return number of additional command-line arguments 122 */ 123 size_t args() const; 124 125 /** 126 * Add argument at the end of command line 127 * @param value argument value 128 * @return status of operation 129 */ 130 status_t add_arg(const LSPString *value); 131 132 /** 133 * Add argument at the end of command line 134 * @param value argument value in UTF-8 encoding 135 * @return status of operation 136 */ 137 status_t add_arg(const char *value); 138 139 /** 140 * Set value of argument at the specified place 141 * @param value argument value 142 * @return status of operation 143 */ 144 status_t set_arg(size_t index, const LSPString *value); 145 146 /** 147 * Set value of argument at the specified place 148 * @param value argument value in UTF-8 encoding 149 * @return status of operation 150 */ 151 status_t set_arg(size_t index, const char *value); 152 153 /** 154 * Get value of argument at the specified place 155 * @param value pointer to store argument value 156 * @return status of operation 157 */ 158 status_t get_arg(size_t index, LSPString *value); 159 160 /** 161 * Get value of argument at the specified place 162 * @param value pointer to store argument value 163 * @return status of operation 164 */ 165 status_t get_arg(size_t index, char **value); 166 167 /** 168 * Remove the argument at the specified place 169 * @param value pointer to store value of removed argument 170 * @return status of operation 171 */ 172 status_t remove_arg(size_t index, LSPString *value = NULL); 173 174 /** 175 * Remove the argument at the specified place 176 * @param value pointer to store value of removed argument. 177 * The pointer should be free()'d after use 178 * @return status of operation 179 */ 180 status_t remove_arg(size_t index, char **value = NULL); 181 182 /** 183 * Insert argument at the specified position 184 * @param value argument value 185 * @return status of operation 186 */ 187 status_t insert_arg(size_t index, const LSPString *value); 188 189 /** 190 * Insert argument at the specified position 191 * @param value argument value in UTF-8 encoding 192 * @return status of operation 193 */ 194 status_t insert_arg(size_t index, const char *value); 195 196 /** 197 * Clear arguments; 198 * @return status of operation 199 */ 200 status_t clear_args(); 201 202 public: 203 /** 204 * Return number of environment variables 205 * @return number of environment variables 206 */ 207 size_t envs() const; 208 209 /** 210 * Set value of the specific environment variable 211 * @param key the name of environment variable 212 * @param value the value of environment variable 213 * @return status of operation 214 */ 215 status_t set_env(const LSPString *key, const LSPString *value); 216 217 /** 218 * Set value of the specific environment variable 219 * @param key the name of environment variable in UTF-8 encoding 220 * @param value the value of environment variable in UTF-8 encoding 221 * @return status of operation 222 */ 223 status_t set_env(const char *key, const char *value); 224 225 /** 226 * Remove the specific environment variable 227 * @param key the name of environment variable 228 * @param pointer to store value of the removed environment variable 229 * @return status of operation 230 */ 231 status_t remove_env(const LSPString *key, LSPString *value = NULL); 232 233 /** 234 * Remove the specific environment variable 235 * @param key the name of environment variable 236 * @param pointer to store value of the removed environment variable 237 * @return status of operation 238 */ 239 status_t remove_env(const char *key, LSPString *value = NULL); 240 241 /** 242 * Remove the specific environment variable 243 * @param key the name of environment variable in UTF-8 encoding 244 * @param pointer to store value of the removed environment variable in UTF-8 encoding. 245 * The obtained pointer should be free()'d after use 246 * @return status of operation 247 */ 248 status_t remove_env(const char *key, char **value = NULL); 249 250 /** 251 * Obtain the value of the specific environment variable 252 * @param key the name of environment variable 253 * @param pointer to store value of the environment variable 254 * @return status of operation 255 */ 256 status_t get_env(const LSPString *key, LSPString *value = NULL); 257 258 /** 259 * Obtain the value of the specific environment variable 260 * @param key the name of environment variable 261 * @param pointer to store value of the environment variable 262 * @return status of operation 263 */ 264 status_t get_env(const char *key, LSPString *value = NULL); 265 266 /** 267 * Obtain the value of the specific environment variable 268 * @param key the name of environment variable in UTF-8 encoding 269 * @param pointer to store value of the environment variable in UTF-8 encoding. 270 * The obtained pointer should be free()'d after use 271 * @return status of operation 272 */ 273 status_t get_env(const char *key, char **value = NULL); 274 275 /** 276 * Obtain the key and value of environment variable by index 277 * @param idx the environment variable index 278 * @param key environment variable key 279 * @param value environment variable value 280 * @return status of operation 281 */ 282 status_t read_env(size_t idx, LSPString *key = NULL, LSPString *value = NULL); 283 284 /** 285 * Obtain the value of the specific environment variable 286 * @param idx the environment variable index 287 * @param key the name of environment variable in UTF-8 encoding 288 * The obtained pointer should be free()'d after use 289 * @param pointer to store value of the environment variable in UTF-8 encoding. 290 * The obtained pointer should be free()'d after use 291 * @return status of operation 292 */ 293 status_t read_env(size_t idx, char **key = NULL, char **value = NULL); 294 295 /** 296 * Clear all environment variables 297 * @return status of operation 298 */ 299 status_t clear_env(); 300 301 public: 302 /** 303 * Return redirected standard input stream of the process. 304 * The redirection is allowed before successful launch() has been issued. 305 * 306 * @return pointer to standard input stream 307 */ 308 io::IOutStream *get_stdin(); 309 310 /** 311 * Return redirected standard output stream of the process. 312 * The redirection is allowed before successful launch() has been issued. 313 * 314 * @return pointer to standard output stream 315 */ 316 io::IInStream *get_stdout(); 317 318 /** 319 * Return redirected standard error stream of the process. 320 * The redirection is allowed before successful launch() has been issued. 321 * 322 * @return pointer to standard error stream 323 */ 324 io::IInStream *get_stderr(); 325 326 /** 327 * Get process status 328 * @return process status 329 */ 330 size_t status(); 331 332 /** 333 * Copy environment variables of the current process 334 * @return status of operation 335 */ 336 status_t copy_env(); 337 338 /** 339 * Launch the process 340 * @return status of operation 341 */ 342 status_t launch(); 343 344 /** 345 * Chech that the object is not in error state 346 * @return true if object is in not error state 347 */ 348 bool valid(); 349 350 /** 351 * Check that process is in running state 352 * @return true if process is in running state 353 */ 354 bool running(); 355 356 /** 357 * Check that process has exited 358 * @return true if process has exited 359 */ 360 bool exited(); 361 362 /** 363 * Get unique process identifier 364 * @return process identifier 365 */ 366 ssize_t process_id() const; 367 368 /** 369 * Wait for the process termination 370 * @param millis number of milliseconds to wait, negative value means infinite wait 371 * @return status of operation 372 */ 373 status_t wait(wssize_t millis = -1); 374 375 /** 376 * Get process exit status 377 * @param code pointer to save exit status 378 * @return status of operation 379 */ 380 status_t exit_code(int *code); 381 }; 382 383 } /* namespace ipc */ 384 } /* namespace lsp */ 385 386 #endif /* CORE_IPC_PROCESS_H_ */ 387