1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
#ifndef TANGO_TESTS_CATCH2_UTILS_PLATFORM_UNIX_INTERFACE_H
#define TANGO_TESTS_CATCH2_UTILS_PLATFORM_UNIX_INTERFACE_H
#include <memory>
#include <cstring>
#include <stdexcept>
#include <sstream>
namespace TangoTest::platform::unix
{
template <typename... Args>
[[noreturn]] void throw_strerror(Args... args)
{
std::stringstream ss;
(ss << ... << args);
ss << ": " << std::strerror(errno);
throw std::runtime_error(ss.str());
}
// To be implemented by Linux and macOS implementations
// Watches a file for `write()` events and notifies a user by sending events which can
// be read from a file descriptor.
class FileWatcher
{
public:
// Construct the FileWatcher monitoring the file at `filename` for `write()`
// events.
//
// Requires that `filename` exists.
explicit FileWatcher(const char *filename);
FileWatcher(const FileWatcher &) = delete;
FileWatcher &operator=(FileWatcher &) = delete;
virtual ~FileWatcher();
// Return a file descriptor that can be `select()`'d on.
//
// The file descriptor becomes readable whenever a "write event" occurs.
//
// Spurious wake-ups are possible, that is the file descriptor could become
// readable even when no write event has occurred.
int get_file_descriptor();
// Read and discard a single `write()` event.
void pop_event();
// Start the file watcher thread on macOS.
// On Linux do nothing.
void start_watching();
// Stop the file watcher thread on macOS and close all fds.
// On Linux do nothing.
void stop_watching();
// Cleanup any resources created by the `FileWatcher` which survive a
// `fork()`.
//
// This is intended to allow a user to constructor a `FileWatcher` before
// calling `fork()` then cleanup any resources in the child process.
//
// This is required so that the user will not miss a `write()` event.
void cleanup_in_child();
private:
struct Impl;
std::unique_ptr<Impl> m_pimpl;
};
// Arranges for this process to die if this process's parent is not `ppid`,
// i.e. because they parent has died and this process has been re-parented.
void kill_self_on_parent_death(pid_t ppid);
} // namespace TangoTest::platform::unix
#endif
|