2016-06-15 03:32:35 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "common.hpp"
|
|
|
|
#include "components/logger.hpp"
|
2019-03-07 05:22:00 +00:00
|
|
|
#include "components/types.hpp"
|
2016-12-05 19:41:00 +00:00
|
|
|
#include "errors.hpp"
|
2021-10-12 17:33:15 +00:00
|
|
|
#include "utils/file.hpp"
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-19 05:22:44 +00:00
|
|
|
POLYBAR_NS
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-12-20 04:05:43 +00:00
|
|
|
DEFINE_ERROR(command_error);
|
|
|
|
|
2022-03-06 16:44:48 +00:00
|
|
|
enum class output_policy {
|
|
|
|
REDIRECTED,
|
|
|
|
IGNORED,
|
|
|
|
};
|
|
|
|
|
2016-12-20 04:05:43 +00:00
|
|
|
/**
|
|
|
|
* Wrapper used to execute command in a subprocess.
|
|
|
|
* In-/output streams are opened to enable ipc.
|
2022-03-06 16:44:48 +00:00
|
|
|
* If the command is created using command<output_policy::REDIRECTED>, the child streams are
|
2019-03-07 05:22:00 +00:00
|
|
|
* redirected and you can read the program output or write into the program input.
|
|
|
|
*
|
2022-03-06 16:44:48 +00:00
|
|
|
* If the command is created using command<output_policy::IGNORED>, the output is not redirected and
|
2019-03-07 05:22:00 +00:00
|
|
|
* you can't communicate with the child program.
|
2016-12-20 04:05:43 +00:00
|
|
|
*
|
|
|
|
* Example usage:
|
|
|
|
*
|
2022-02-20 20:40:48 +00:00
|
|
|
* @code cpp
|
2022-03-06 16:44:48 +00:00
|
|
|
* command<output_policy::REDIRECTED>auto(m_log, "cat /etc/rc.local");
|
2016-12-20 04:05:43 +00:00
|
|
|
* cmd->exec();
|
|
|
|
* cmd->tail([](string s) { std::cout << s << std::endl; });
|
2022-02-20 20:40:48 +00:00
|
|
|
* @endcode
|
2016-12-20 04:05:43 +00:00
|
|
|
*
|
2022-02-20 20:40:48 +00:00
|
|
|
* @code cpp
|
2022-03-06 16:44:48 +00:00
|
|
|
* command<output_policy::REDIRECTED>auto(m_log, "for i in 1 2 3; do echo $i; done");
|
2016-12-20 04:05:43 +00:00
|
|
|
* cmd->exec();
|
|
|
|
* cout << cmd->readline(); // 1
|
|
|
|
* cout << cmd->readline() << cmd->readline(); // 23
|
2022-02-20 20:40:48 +00:00
|
|
|
* @endcode
|
2019-03-07 05:22:00 +00:00
|
|
|
*
|
2022-02-20 20:40:48 +00:00
|
|
|
* @code cpp
|
2022-03-06 16:44:48 +00:00
|
|
|
* command<output_policy::IGNORED>auto(m_log, "ping kernel.org");
|
2019-03-07 05:22:00 +00:00
|
|
|
* int status = cmd->exec();
|
2022-02-20 20:40:48 +00:00
|
|
|
* @endcode
|
2016-12-20 04:05:43 +00:00
|
|
|
*/
|
2019-03-07 05:22:00 +00:00
|
|
|
template <output_policy>
|
|
|
|
class command;
|
|
|
|
|
|
|
|
template <>
|
|
|
|
class command<output_policy::IGNORED> {
|
2016-12-20 04:05:43 +00:00
|
|
|
public:
|
|
|
|
explicit command(const logger& logger, string cmd);
|
2019-03-07 05:22:00 +00:00
|
|
|
command(const command&) = delete;
|
2016-12-20 04:05:43 +00:00
|
|
|
~command();
|
|
|
|
|
2019-03-07 05:22:00 +00:00
|
|
|
command& operator=(const command&) = delete;
|
|
|
|
|
2016-12-20 04:05:43 +00:00
|
|
|
int exec(bool wait_for_completion = true);
|
|
|
|
void terminate();
|
|
|
|
bool is_running();
|
|
|
|
int wait();
|
|
|
|
|
|
|
|
pid_t get_pid();
|
|
|
|
int get_exit_status();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
const logger& m_log;
|
|
|
|
|
|
|
|
string m_cmd;
|
|
|
|
|
2021-10-02 23:27:11 +00:00
|
|
|
pid_t m_forkpid{-1};
|
|
|
|
int m_forkstatus{-1};
|
2019-03-07 05:22:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
class command<output_policy::REDIRECTED> : private command<output_policy::IGNORED> {
|
|
|
|
public:
|
|
|
|
explicit command(const logger& logger, string cmd);
|
|
|
|
command(const command&) = delete;
|
|
|
|
~command();
|
|
|
|
|
|
|
|
command& operator=(const command&) = delete;
|
|
|
|
|
2021-09-28 19:06:40 +00:00
|
|
|
int exec(bool wait_for_completion = true, const vector<pair<string, string>>& env = {});
|
2019-03-07 05:22:00 +00:00
|
|
|
using command<output_policy::IGNORED>::terminate;
|
|
|
|
using command<output_policy::IGNORED>::is_running;
|
|
|
|
using command<output_policy::IGNORED>::wait;
|
|
|
|
|
|
|
|
using command<output_policy::IGNORED>::get_pid;
|
|
|
|
using command<output_policy::IGNORED>::get_exit_status;
|
|
|
|
|
2022-01-22 21:00:26 +00:00
|
|
|
void tail(std::function<void(string)> cb);
|
2019-03-07 05:22:00 +00:00
|
|
|
string readline();
|
2024-04-28 19:10:12 +00:00
|
|
|
bool wait_for_data(int timeout_ms);
|
2019-03-07 05:22:00 +00:00
|
|
|
|
|
|
|
int get_stdout(int c);
|
|
|
|
int get_stdin(int c);
|
|
|
|
|
|
|
|
protected:
|
2021-10-02 23:27:11 +00:00
|
|
|
int m_stdout[2]{0, 0};
|
|
|
|
int m_stdin[2]{0, 0};
|
2016-12-20 04:05:43 +00:00
|
|
|
|
2021-10-02 23:27:11 +00:00
|
|
|
unique_ptr<fd_stream<std::istream>> m_stdout_reader{nullptr};
|
2016-12-20 04:05:43 +00:00
|
|
|
};
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-19 05:22:44 +00:00
|
|
|
POLYBAR_NS_END
|