polybar/include/utils/command.hpp

107 lines
2.6 KiB
C++
Raw Normal View History

2016-06-15 03:32:35 +00:00
#pragma once
#include "common.hpp"
#include "components/logger.hpp"
#include "components/types.hpp"
#include "errors.hpp"
#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
DEFINE_ERROR(command_error);
2022-03-06 16:44:48 +00:00
enum class output_policy {
REDIRECTED,
IGNORED,
};
/**
* 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
* 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
* you can't communicate with the child program.
*
* 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");
* cmd->exec();
* cmd->tail([](string s) { std::cout << s << std::endl; });
2022-02-20 20:40:48 +00:00
* @endcode
*
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");
* cmd->exec();
* cout << cmd->readline(); // 1
* cout << cmd->readline() << cmd->readline(); // 23
2022-02-20 20:40:48 +00:00
* @endcode
*
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");
* int status = cmd->exec();
2022-02-20 20:40:48 +00:00
* @endcode
*/
template <output_policy>
class command;
template <>
class command<output_policy::IGNORED> {
public:
explicit command(const logger& logger, string cmd);
command(const command&) = delete;
~command();
command& operator=(const command&) = delete;
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;
pid_t m_forkpid{-1};
int m_forkstatus{-1};
};
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 = {});
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;
void tail(std::function<void(string)> cb);
string readline();
int get_stdout(int c);
int get_stdin(int c);
protected:
int m_stdout[2]{0, 0};
int m_stdin[2]{0, 0};
unique_ptr<fd_stream<std::istream>> m_stdout_reader{nullptr};
};
2016-06-15 03:32:35 +00:00
2016-11-19 05:22:44 +00:00
POLYBAR_NS_END