// systemd_activated_fd(): the LISTEN_PID/LISTEN_FDS contract, without a real systemd. #include #include #include #include "check.hpp" #include "rpc/systemd_activation.hpp" using namespace velox::daemon::rpc; namespace { void set_env(const char* k, const std::string& v) { ::setenv(k, v.c_str(), 1); } } // namespace void run() { // Not activated: neither var set. ::unsetenv("LISTEN_PID"); ::unsetenv("LISTEN_FDS"); CHECK_EQ(systemd_activated_fd(), -1); // LISTEN_PID for a different process: not us, so not activated. set_env("LISTEN_PID", std::to_string(::getpid() + 1)); set_env("LISTEN_FDS", "1"); CHECK_EQ(systemd_activated_fd(), -1); // Consumed regardless of the outcome — a stale value from some other process's // exec chain must not leak into what veloxd checks next time. CHECK(::getenv("LISTEN_PID") == nullptr); CHECK(::getenv("LISTEN_FDS") == nullptr); // Our own pid, LISTEN_FDS=1: activated, fd 3 (SD_LISTEN_FDS_START). set_env("LISTEN_PID", std::to_string(::getpid())); set_env("LISTEN_FDS", "1"); CHECK_EQ(systemd_activated_fd(), 3); CHECK(::getenv("LISTEN_PID") == nullptr); // Our own pid but LISTEN_FDS=2: a unit file mismatch (veloxd only ever asks for one // socket) — refuse rather than guess which of two fds is the right one. set_env("LISTEN_PID", std::to_string(::getpid())); set_env("LISTEN_FDS", "2"); CHECK_EQ(systemd_activated_fd(), -1); // Garbage LISTEN_FDS: not activated, not a crash. set_env("LISTEN_PID", std::to_string(::getpid())); set_env("LISTEN_FDS", "not-a-number"); CHECK_EQ(systemd_activated_fd(), -1); ::unsetenv("LISTEN_PID"); ::unsetenv("LISTEN_FDS"); } TEST_MAIN()