main.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #define _POSIX_C_SOURCE 200801L
  2. #define _POSIX_SOURCE 200801L
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <signal.h>
  6. #include <errno.h>
  7. #include <time.h>
  8. #include "server.h"
  9. #include "monolog.h"
  10. #include "config.h"
  11. #include "state.h"
  12. #include "rh.h"
  13. #include "toruby.h"
  14. #include "timer.h"
  15. DEFINE_FILE_LOGGER(woe_file_logger);
  16. DEFINE_STDOUT_LOGGER(woe_stdout_logger);
  17. DEFINE_STDERR_LOGGER(woe_stderr_logger);
  18. FILE * woe_start_monolog(char * logname) {
  19. FILE * fout;
  20. monolog_init();
  21. LOG_ENABLE_ERROR();
  22. monolog_enable_level("WARNING");
  23. monolog_enable_level("NOTE");
  24. fout = fopen(logname, "w");
  25. monolog_add_logger(NULL, &woe_stdout_logger);
  26. if (fout) {
  27. monolog_add_logger(fout, &woe_file_logger);
  28. fprintf(stderr, "Opened log file %s %p\n", logname, fout);
  29. } else {
  30. fprintf(stderr, "Could not open log file %s\n", logname);
  31. }
  32. return fout;
  33. }
  34. void woe_stop_monolog() {
  35. monolog_done();
  36. }
  37. int main(int argc, char * argv[]) {
  38. sigset_t signal_set = { { 0 } };
  39. sigset_t signal_old = { { 0 } };
  40. siginfo_t signal_info = { 0 };
  41. struct timespec signal_time = { 0, 10 };
  42. struct woe_state state = { 0 };
  43. struct woe_config config = { 0 };
  44. state.config = &config;
  45. FILE * logfile = NULL;
  46. state.mrb = mrb_open();
  47. state.mrb->ud = &state;
  48. tr_init(state.mrb);
  49. woe_config_init_args(state.config, argc, argv);
  50. logfile = woe_start_monolog(state.config->log_file);
  51. state.server = woe_server_new(state.config->port);
  52. woe_server_set_mrb(state.server, state.mrb);
  53. /* Handle all signals, except a few. */
  54. sigfillset(&signal_set);
  55. sigdelset(&signal_set, SIGKILL);
  56. sigdelset(&signal_set, SIGTERM);
  57. sigdelset(&signal_set, SIGINT);
  58. sigdelset(&signal_set, SIGSEGV);
  59. sigdelset(&signal_set, SIGTSTP);
  60. /* Ignore them all, because we will wait for them in stead. */
  61. sigprocmask(SIG_SETMASK, &signal_set, &signal_old);
  62. rh_run_script(state.mrb, "main.rb");
  63. if (woe_server_listen(state.server) > 0) {
  64. LOG_ERROR("Cannot listen. Stop.");
  65. } else {
  66. rh_run_toplevel(state.mrb, "woe_on_start", "");
  67. while (woe_server_busy(state.server)) {
  68. int caught = 0;
  69. siginfo_t info;
  70. struct woe_timer * timer;
  71. info.si_value.sival_ptr = NULL;
  72. woe_server_update(state.server, 1);
  73. caught = sigtimedwait(&signal_set, &info, &signal_time);
  74. if (caught > 0) {
  75. timer = info.si_value.sival_ptr;
  76. if (timer) {
  77. LOG_DEBUG("Received timer signal %d, %d\n", caught, timer->index);
  78. woe_timer_callback(timer);
  79. } else {
  80. LOG_NOTE("Received signal %d\n", caught);
  81. rh_run_toplevel(state.mrb, "woe_on_signal", "i", caught);
  82. }
  83. }
  84. }
  85. }
  86. rh_run_toplevel(state.mrb, "woe_on_stop", "");
  87. woe_server_free(state.server);
  88. mrb_close(state.mrb);
  89. LOG_NOTE("Shutting down WOE\n");
  90. woe_stop_monolog();
  91. return 0;
  92. }