Files
pip/libs/main/system/piprocess.h
2025-08-13 22:35:43 +03:00

263 lines
12 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \file piprocess.h
* \ingroup System
* \~\brief
* \~english External process
* \~russian Внешний процесс
*/
/*
PIP - Platform Independent Primitives
Process
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIPROCESS_H
#define PIPROCESS_H
#ifndef MICRO_PIP
# include "pithread.h"
//! \class PIProcess
//! \ingroup System
//! \~english
//! \brief Class for managing external processes
//! \details
//! The PIProcess class provides functionality to create, control and interact with external processes.
//! It allows both attached execution (with full control over input/output streams) and detached execution.
//!
//! Key features:
//! - Start processes with arguments and environment variables
//! - Monitor process state (running/finished)
//! - Read from stdout/stderr streams
//! - Write to stdin stream
//! - Set custom working directory
//! - Modify environment variables
//! - Wait for process completion
//! - Terminate processes
//! - Retrieve exit codes and process IDs
//!
//! This class inherits from PIThread and provides event-based notifications for process lifecycle events.
//! \~russian
//! \brief Класс для управления внешними процессами
//! \details
//! Класс PIProcess предоставляет функциональность для создания, управления и взаимодействия с внешними процессами.
//! Поддерживает как присоединенное выполнение (с полным контролем потоков ввода/вывода), так и независимое выполнение.
//!
//! Основные возможности:
//! - Запуск процессов с аргументами и переменными окружения
//! - Мониторинг состояния процесса (запущен/завершен)
//! - Чтение из потоков stdout/stderr
//! - Запись в поток stdin
//! - Установка рабочей директории
//! - Изменение переменных окружения
//! - Ожидание завершения процесса
//! - Завершение процессов
//! - Получение кодов завершения и идентификаторов процессов
//!
class PIP_EXPORT PIProcess: public PIThread {
PIOBJECT_SUBCLASS(PIProcess, PIThread);
public:
//! \~english Construct empty %PIProcess
//! \~russian Создает пустой %PIProcess
PIProcess();
virtual ~PIProcess();
//! \~english Returns last attached execution exit code
//! \~russian Возвращает код завершения последнего выполнения
int exitCode() const { return exit_code; }
//! \~english Returns current attached execution process ID
//! \~russian Возвращает ID процесса текущего выполнения
int pID() const;
//! \~english Returns current attached execution working directory or empty string if it wasn`t set
//! \~russian Возвращает рабочую директорию выполнения или пустую строку, если не установлена
PIString workingDirectory() const { return wd; }
//! \~english Set attached execution working directory
//! \~russian Устанавливает рабочую директорию для выполнения
void setWorkingDirectory(const PIString & path) { wd = path; }
//! \~english Rseet attached execution working directory, application working dir will be used
//! \~russian Сбрасывает рабочую директорию, будет использоваться директория приложения
void resetWorkingDirectory() { wd.clear(); }
//! \~english Returns all attached execution output stream
//! \~russian Возвращает весь вывод из стандартного потока вывода (stdout)
PIByteArray readOutput();
//! \~english Returns all attached execution error stream
//! \~russian Возвращает весь вывод из потока ошибок (stderr)
PIByteArray readError();
//! \~english Write data to attached execution input stream
//! \~russian Записывает данные в стандартный поток ввода (stdin)
bool writeInput(const PIByteArray & data);
//! \~english Close attached execution input stream and send EOF
//! \~russian Закрывает поток ввода (stdin) и отправляет EOF
void closeInput();
//! \~english Enable or disable writing to process stdin
//! \~russian Включает или отключает запись в стандартный поток ввода (stdin) процесса
void enableWriteStdIn(bool on = true);
//! \~english Enable or disable reading from process stdout
//! \~russian Включает или отключает чтение из стандартного потока вывода (stdout) процесса
void enableReadStdOut(bool on = true);
//! \~english Enable or disable reading from process stderr
//! \~russian Включает или отключает чтение из потока ошибок (stderr) процесса
void enableReadStdErr(bool on = true);
//! \~english Returns current attached execution environment
//! \~russian Возвращает текущее окружение выполнения
PIStringList environment() { return env; }
//! \~english Clear current attached execution environment. Call before \a exec()
//! \~russian Очищает окружение выполнения. Вызывать перед \a exec()
void clearEnvironment() { env.clear(); }
//! \~english Remove variable "variable" from current attached execution environment. Call before \a exec()
//! \~russian Удаляет переменную "variable" из окружения выполнения. Вызывать перед \a exec()
void removeEnvironmentVariable(const PIString & variable);
//! \~english Set variable "variable" to "value" in current attached execution environment. Call before \a exec()
//! \~russian Устанавливает значение "value" для переменной "variable" в окружении выполнения. Вызывать перед \a exec()
void setEnvironmentVariable(const PIString & variable, const PIString & value);
//! \~english Start attached execution "program" with one argument "arg"
//! \~russian Запускает выполнение "program" с одним аргументом "arg"
void exec(const PIString & program, const PIString & arg) {
args.clear();
args << program << arg;
exec_();
}
EVENT_HANDLER1(void, exec, const PIString &, program) {
args.clear();
args << program;
exec_();
}
EVENT_HANDLER2(void, exec, const PIString &, program, const PIStringList &, args_) {
args.clear();
args << program << args_;
exec_();
}
EVENT_HANDLER(void, terminate);
EVENT_HANDLER(bool, waitForFinish) { return PIThread::waitForFinish(); }
EVENT_HANDLER1(bool, waitForFinish, PISystemTime, timeout) { return PIThread::waitForFinish(timeout); }
EVENT1(execStarted, PIString, program);
EVENT2(execFinished, PIString, program, int, exit_code);
//! \~english Check if attached execution has finished
//! \~russian Проверяет, завершилось ли выполнение процесса
bool isExecFinished() const { return exec_finished; }
//! \~english Check if attached execution has started
//! \~russian Проверяет, запущен ли процесс выполнения
bool isExecStarted() const { return exec_start; }
//! \~english Start detached execution "program" without arguments
//! \~russian Запускает независимое выполнение "program" без аргументов
static void execIndependent(const PIString & program) { execIndependent(program, PIStringList()); }
//! \~english Start detached execution "program" with one argument "arg"
//! \~russian Запускает независимое выполнение "program" с одним аргументом "arg"
static void execIndependent(const PIString & program, const PIString & arg) { execIndependent(program, PIStringList() << arg); }
//! \~english Start detached execution "program" with arguments "args"
//! \~russian Запускает независимое выполнение "program" с аргументами "args"
static void execIndependent(const PIString & program, const PIStringList & args);
//! \~english Returns application environment
//! \~russian Возвращает окружение текущего приложения
static PIStringList currentEnvironment();
//! \~english Returns application process ID
//! \~russian Возвращает ID процесса текущего приложения
static int currentPID();
//! \~english Returns variable "variable" value from application environment
//! \~russian Возвращает значение переменной "variable" из окружения приложения
static PIString getEnvironmentVariable(const PIString & variable);
//! \handlers
//! \{
//! \fn void exec(const PIString & program)
//! \brief
//! \~english Start attached execution "program" without arguments
//! \~russian Запускает выполнение "program" без аргументов
//! \fn void exec(const PIString & program, const PIStringList & args)
//! \brief
//! \~english Start attached execution "program" with arguments "args"
//! \~russian Запускает выполнение "program" с аргументами "args"
//! \fn void terminate()
//! \brief
//! \~english Immediately terminate attached execution
//! \~russian Немедленно завершает выполнение
//! \fn bool waitForFinish()
//! \brief
//! \~english Wait for attached execution finish maximum for 60 seconds
//! \~russian Ожидает завершения выполнения (максимум 60 секунд)
//! \fn bool waitForFinish(PISystemTime timeout)
//! \brief
//! \~english Wait for attached execution finish maximum for "timeout_"
//! \~russian Ожидает завершения выполнения в течение "timeout_"
//! \}
//! \events
//! \{
//! \fn void execStarted(PIString program)
//! \brief
//! \~english Raise on attached execution start
//! \~russian Генерируется при запуске выполнения
//! \fn void execFinished(PIString program)
//! \brief
//! \~english Raise on attached execution finish
//! \~russian Генерируется при завершении выполнения
//! \}
private:
void run() override;
void exec_();
void startProc(bool detached);
private:
PRIVATE_DECLARATION(PIP_EXPORT)
PIStringList args, env;
PIString wd;
int exit_code;
std::atomic_bool exec_start;
std::atomic_bool exec_finished;
};
#endif // MICRO_PIP
#endif // PIPROCESS_H