1 /* A simple standalone XML-RPC server based on Abyss that contains a
2 simple one-thread request processing loop.
4 xmlrpc_sample_add_server.c is a server that does the same thing, but
5 does it by running a full Abyss daemon in the background, so it has
6 less control over how the requests are served.
12 #include <xmlrpc-c/base.h>
13 #include <xmlrpc-c/abyss.h>
14 #include <xmlrpc-c/server.h>
15 #include <xmlrpc-c/server_abyss.h>
17 #include "config.h" /* information about this build environment */
21 setupSignalHandlers(void) {
23 /* In UNIX, when you try to write to a socket that has been closed
24 from the other end, your write fails, but you also get a SIGPIPE
25 signal. That signal will kill you before you even have a chance
26 to see the write fail unless you catch, block, or ignore it.
27 If a client should connect to us and then disconnect before we've
28 sent our response, we see this socket-closed behavior. We
29 obviously don't want to die just because a client didn't complete
30 an RPC, so we ignore SIGPIPE.
32 struct sigaction mysigaction;
34 sigemptyset(&mysigaction.sa_mask);
35 mysigaction.sa_flags = 0;
36 mysigaction.sa_handler = SIG_IGN;
37 sigaction(SIGPIPE, &mysigaction, NULL);
43 sample_add(xmlrpc_env * const envP,
44 xmlrpc_value * const paramArrayP,
45 void * const userData ATTR_UNUSED) {
49 /* Parse our argument array. */
50 xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
51 if (envP->fault_occurred)
54 /* Add our two numbers. */
57 /* Return our result. */
58 return xmlrpc_build_value(envP, "i", z);
63 static xmlrpc_server_shutdown_fn requestShutdown;
66 requestShutdown(xmlrpc_env * const envP,
68 const char * const comment) {
70 /* You make this run by executing the system method
71 'system.shutdown'. This function is registered in the method
72 registry as the thing to call for that.
74 int * const terminationRequestedP = context;
76 xmlrpc_env_init(envP);
78 fprintf(stderr, "Termination requested: %s\n", comment);
80 *terminationRequestedP = 1;
87 const char ** const argv) {
90 xmlrpc_registry * registryP;
92 int terminationRequested; /* A boolean value */
95 fprintf(stderr, "You must specify 1 argument: The TCP port number "
96 "on which to listen for XML-RPC calls. "
97 "You specified %d.\n", argc-1);
101 xmlrpc_env_init(&env);
103 registryP = xmlrpc_registry_new(&env);
105 xmlrpc_registry_add_method(
106 &env, registryP, NULL, "sample.add", &sample_add, NULL);
108 xmlrpc_registry_set_shutdown(registryP,
109 &requestShutdown, &terminationRequested);
111 ServerCreate(&abyssServer, "XmlRpcServer", atoi(argv[1]), NULL, NULL);
113 xmlrpc_server_abyss_set_handlers(&abyssServer, registryP);
115 ServerInit(&abyssServer);
117 setupSignalHandlers();
119 terminationRequested = 0;
121 while (!terminationRequested) {
122 printf("Waiting for next RPC...\n");
124 ServerRunOnce(&abyssServer);
125 /* This waits for the next connection, accepts it, reads the
126 HTTP POST request, executes the indicated RPC, and closes
131 ServerFree(&abyssServer);