1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
/* A simple standalone XML-RPC server based on Abyss that processes a
single RPC from an existing TCP connection on Standard Input.
A typical example of where this would be useful is with an Inetd
"super server."
xmlrpc_sample_add_server.c is a server that does the same thing,
but you give it a TCP port number and it listens for TCP connecitons
and processes RPCs ad infinitum.
*/
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/abyss.h>
#include <xmlrpc-c/server.h>
#include <xmlrpc-c/server_abyss.h>
#include "config.h" /* information about this build environment */
static void
setupSignalHandlers(void) {
/* In UNIX, when you try to write to a socket that has been closed
from the other end, your write fails, but you also get a SIGPIPE
signal. That signal will kill you before you even have a chance
to see the write fail unless you catch, block, or ignore it.
If a client should connect to us and then disconnect before we've
sent our response, we see this socket-closed behavior. We
obviously don't want to die just because a client didn't complete
an RPC, so we ignore SIGPIPE.
*/
struct sigaction mysigaction;
sigemptyset(&mysigaction.sa_mask);
mysigaction.sa_flags = 0;
mysigaction.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &mysigaction, NULL);
}
static xmlrpc_value *
sample_add(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
void * const userData ATTR_UNUSED) {
xmlrpc_int x, y, z;
/* Parse our argument array. */
xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
if (envP->fault_occurred)
return NULL;
/* Add our two numbers. */
z = x + y;
/* Return our result. */
return xmlrpc_build_value(envP, "i", z);
}
int
main(int const argc,
const char ** const argv) {
TServer abyssServer;
xmlrpc_registry * registryP;
xmlrpc_env env;
if (argc-1 != 0) {
fprintf(stderr, "There are no arguments. You must supply a "
"bound socket on which to listen for client connections "
"as Standard Input\n");
if (argv) {} /* silence unused parameter warning */
exit(1);
}
xmlrpc_env_init(&env);
registryP = xmlrpc_registry_new(&env);
xmlrpc_registry_add_method(
&env, registryP, NULL, "sample.add", &sample_add, NULL);
ServerCreateNoAccept(&abyssServer, "XmlRpcServer", NULL, NULL);
xmlrpc_server_abyss_set_handlers(&abyssServer, registryP);
setupSignalHandlers();
ServerRunConn(&abyssServer, STDIN_FILENO);
/* This reads the HTTP POST request from Standard Input and
executes the indicated RPC.
*/
ServerFree(&abyssServer);
return 0;
}
|