interrupted_server.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* A simple standalone XML-RPC server program based on Abyss.
  2. You can terminate this server in controlled fashion with a SIGTERM
  3. signal.
  4. xmlrpc_sample_add_server.c is a server that does the same thing with
  5. simpler code, but it is not interruptible with SIGTERM.
  6. */
  7. #define _XOPEN_SOURCE 600
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <signal.h>
  11. #include <sys/socket.h>
  12. #include <netinet/in.h>
  13. #include <xmlrpc-c/base.h>
  14. #include <xmlrpc-c/abyss.h>
  15. #include <xmlrpc-c/server.h>
  16. #include <xmlrpc-c/server_abyss.h>
  17. #include "config.h" /* information about this build environment */
  18. static void
  19. dieIfFailed(const char * const description,
  20. xmlrpc_env const env) {
  21. if (env.fault_occurred) {
  22. fprintf(stderr, "%s failed. %s\n", description, env.fault_string);
  23. exit(1);
  24. }
  25. }
  26. static xmlrpc_server_abyss_t * serverToTerminateP;
  27. static void
  28. sigtermHandler(int const signalClass) {
  29. xmlrpc_env env;
  30. xmlrpc_env_init(&env);
  31. xmlrpc_server_abyss_terminate(&env, serverToTerminateP);
  32. dieIfFailed("xmlrpc_server_abyss_terminate", env);
  33. xmlrpc_env_clean(&env);
  34. }
  35. static void
  36. setupSigtermHandler(xmlrpc_server_abyss_t * const serverP) {
  37. struct sigaction mysigaction;
  38. serverToTerminateP = serverP;
  39. sigemptyset(&mysigaction.sa_mask);
  40. mysigaction.sa_flags = 0;
  41. mysigaction.sa_handler = sigtermHandler;
  42. sigaction(SIGTERM, &mysigaction, NULL);
  43. }
  44. static void
  45. restoreSigtermHandler(void){
  46. struct sigaction mysigaction;
  47. sigemptyset(&mysigaction.sa_mask);
  48. mysigaction.sa_flags = 0;
  49. mysigaction.sa_handler = SIG_DFL;
  50. sigaction(SIGTERM, &mysigaction, NULL);
  51. }
  52. static xmlrpc_value *
  53. sample_add(xmlrpc_env * const envP,
  54. xmlrpc_value * const paramArrayP,
  55. void * const serverInfo,
  56. void * const channelInfo) {
  57. xmlrpc_int x, y, z;
  58. /* Parse our argument array. */
  59. xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
  60. if (envP->fault_occurred)
  61. return NULL;
  62. /* Add our two numbers. */
  63. z = x + y;
  64. /* Return our result. */
  65. return xmlrpc_build_value(envP, "i", z);
  66. }
  67. int
  68. main(int const argc,
  69. const char ** const argv) {
  70. struct xmlrpc_method_info3 const methodInfo = {
  71. .methodName = "sample.add",
  72. .methodFunction = &sample_add,
  73. .serverInfo = NULL
  74. };
  75. xmlrpc_server_abyss_parms serverparm;
  76. xmlrpc_server_abyss_t * serverP;
  77. xmlrpc_registry * registryP;
  78. xmlrpc_env env;
  79. xmlrpc_server_abyss_sig * oldHandlersP;
  80. if (argc-1 != 1) {
  81. fprintf(stderr, "You must specify 1 argument: The TCP port number "
  82. "on which to listen for XML-RPC calls. "
  83. "You specified %d.\n", argc-1);
  84. exit(1);
  85. }
  86. xmlrpc_env_init(&env);
  87. xmlrpc_server_abyss_global_init(&env);
  88. dieIfFailed("xmlrpc_server_abyss_global_init", env);
  89. registryP = xmlrpc_registry_new(&env);
  90. dieIfFailed("xmlrpc_registry_new", env);
  91. xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
  92. dieIfFailed("xmlrpc_registry_add_method2", env);
  93. serverparm.config_file_name = NULL;
  94. serverparm.registryP = registryP;
  95. serverparm.port_number = atoi(argv[1]);
  96. xmlrpc_server_abyss_create(&env, &serverparm, XMLRPC_APSIZE(port_number),
  97. &serverP);
  98. dieIfFailed("xmlrpc_server_abyss_create", env);
  99. xmlrpc_server_abyss_setup_sig(&env, serverP, &oldHandlersP);
  100. dieIfFailed("xmlrpc_server_abyss_setup_sig", env);
  101. setupSigtermHandler(serverP);
  102. printf("Running XML-RPC server...\n");
  103. xmlrpc_server_abyss_run_server(&env, serverP);
  104. dieIfFailed("xmlrpc_server_abyss_run_server", env);
  105. printf("Server has terminated\n");
  106. restoreSigtermHandler();
  107. xmlrpc_server_abyss_restore_sig(oldHandlersP);
  108. xmlrpc_server_abyss_destroy(serverP);
  109. xmlrpc_registry_free(registryP);
  110. xmlrpc_server_abyss_global_term();
  111. xmlrpc_env_clean(&env);
  112. return 0;
  113. }