posix_daemon_control.cpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include<__vic/posix/daemon_control.h>
  2. #include<iostream>
  3. #include<exception>
  4. #include<cstring>
  5. #include<cassert>
  6. #include<csignal>
  7. #include<unistd.h>
  8. #include<sys/wait.h>
  9. namespace tests {
  10. static const char * const pid_file_name = "daemon_control.pid";
  11. using __vic::posix::daemon_control;
  12. volatile std::sig_atomic_t finish = 0;
  13. extern "C" void sigterm_handler(int ) { finish = 1; }
  14. void daemon_app()
  15. {
  16. daemon_control app(pid_file_name);
  17. app.daemonize();
  18. std::signal(SIGTERM, sigterm_handler);
  19. try {
  20. daemon_control app(pid_file_name);
  21. assert(false);
  22. } catch(const daemon_control::already_running &) {
  23. // Ok
  24. }
  25. while(!finish) ::pause();
  26. }
  27. void control_app(pid_t child_pid)
  28. {
  29. std::cout << "Starting child process..." << std::endl;
  30. ::sleep(1);
  31. assert(daemon_control::control("status", pid_file_name) == 0);
  32. daemon_control::stop_and_wait(pid_file_name);
  33. assert(daemon_control::control("status", pid_file_name) == 1);
  34. int st;
  35. assert(::waitpid(child_pid, &st, WNOHANG) > 0);
  36. try {
  37. daemon_control app(pid_file_name);
  38. assert(daemon_control::control("status", pid_file_name) == 0);
  39. } catch(const daemon_control::already_running &) {
  40. assert(false);
  41. }
  42. assert(daemon_control::control("status", pid_file_name) == 1);
  43. std::cout << "Done\n";
  44. }
  45. void run()
  46. {
  47. switch(pid_t pid = ::fork())
  48. {
  49. case 0: // child
  50. daemon_app();
  51. return;
  52. case -1:
  53. assert(false);
  54. default: // parent
  55. control_app(pid);
  56. }
  57. }
  58. } // namespace
  59. int main(int argc, char *argv[])
  60. {
  61. try
  62. {
  63. if(argc == 2 && std::strcmp(argv[1], "interactive") == 0)
  64. tests::run();
  65. return 0;
  66. }
  67. catch(const std::exception &ex)
  68. {
  69. std::cerr << ex.what() << '\n';
  70. }
  71. return 1;
  72. }