polybar-dwm/include/utils/command.hpp

88 lines
2.0 KiB
C++
Raw Normal View History

2016-06-15 03:32:35 +00:00
#pragma once
#include "common.hpp"
#include "components/logger.hpp"
2016-11-20 22:04:31 +00:00
#include "utils/concurrency.hpp"
#include "utils/functional.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
namespace command_util {
2016-11-02 19:22:45 +00:00
DEFINE_ERROR(command_error);
DEFINE_CHILD_ERROR(command_strerror, command_error);
2016-06-15 03:32:35 +00:00
/**
* Wrapper used to execute command in a subprocess.
* In-/output streams are opened to enable ipc.
*
2016-06-15 03:32:35 +00:00
* Example usage:
*
2016-06-15 03:32:35 +00:00
* @code cpp
* auto cmd = command_util::make_command("cat /etc/rc.local");
2016-06-15 03:32:35 +00:00
* cmd->exec();
* cmd->tail([](string s) { std::cout << s << std::endl; });
* @endcode
2016-06-15 03:32:35 +00:00
*
* @code cpp
* auto cmd = command_util::make_command(
* "while read -r line; do echo data from parent process: $line; done");
* cmd->exec(false);
2016-06-15 03:32:35 +00:00
* cmd->writeline("Test");
* cout << cmd->readline();
* cmd->wait();
* @endcode
2016-06-15 03:32:35 +00:00
*
* @code cpp
* auto cmd = command_util::make_command("for i in 1 2 3; do echo $i; done");
* cmd->exec();
* cout << cmd->readline(); // 1
* cout << cmd->readline() << cmd->readline(); // 23
* @endcode
2016-06-15 03:32:35 +00:00
*/
class command {
public:
2016-11-02 19:22:45 +00:00
explicit command(const logger& logger, string cmd);
~command();
int exec(bool wait_for_completion = true);
void terminate();
bool is_running();
int wait();
2016-12-03 19:52:42 +00:00
void tail(callback<string> cb);
2016-11-02 19:22:45 +00:00
int writeline(string data);
string readline();
int get_stdout(int c);
int get_stdin(int c);
pid_t get_pid();
int get_exit_status();
2016-06-15 03:32:35 +00:00
protected:
const logger& m_log;
string m_cmd;
int m_stdout[2];
int m_stdin[2];
pid_t m_forkpid;
int m_forkstatus;
2016-11-20 22:04:31 +00:00
concurrency_util::spin_lock m_pipelock;
2016-06-15 03:32:35 +00:00
};
using command_t = unique_ptr<command>;
2016-06-15 03:32:35 +00:00
template <typename... Args>
command_t make_command(Args&&... args) {
return make_unique<command>(configure_logger().create<const logger&>(), forward<Args>(args)...);
2016-06-15 03:32:35 +00:00
}
}
using command = command_util::command;
using command_t = command_util::command_t;
2016-11-19 05:22:44 +00:00
POLYBAR_NS_END