diff --git a/buildconf/base.ini b/buildconf/base.ini index 0f478912..ed645dce 100644 --- a/buildconf/base.ini +++ b/buildconf/base.ini @@ -16,7 +16,7 @@ plugins = bin_name = uwsgi append_version = plugin_dir = . -embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness +embedded_plugins = %(main_plugin)s, ping, cache, nagios, rrdtool, carbon, rpc, corerouter, fastrouter, http, ugreen, signal, syslog, rsyslog, logsocket, router_uwsgi, router_redirect, router_basicauth, zergpool, redislog, mongodblog, router_rewrite, router_http, logfile, router_cache, rawrouter, router_static, sslrouter, spooler, cheaper_busyness, symcall as_shared_library = false locking = auto diff --git a/plugins/symcall/symcall_plugin.c b/plugins/symcall/symcall_plugin.c index 2c77f8a3..5498ad91 100644 --- a/plugins/symcall/symcall_plugin.c +++ b/plugins/symcall/symcall_plugin.c @@ -1,33 +1,80 @@ -#include "../../uwsgi.h" +#include extern struct uwsgi_server uwsgi; -int (*symcall_function)(struct wsgi_request *); -int uwsgi_symcall_init(){ - symcall_function = dlsym(RTLD_DEFAULT, "pypy_uwsgi_request"); - uwsgi_log("symcall function ptr: %p\n", symcall_function); - return 0; +struct uwsgi_symcall { + char *symcall_function_name; + int (*symcall_function)(struct wsgi_request *); + + struct uwsgi_string_list *rpc; +} usym; + +struct uwsgi_plugin symcall_plugin; + +static struct uwsgi_option uwsgi_symcall_options[] = { + {"symcall", required_argument, 0, "load the specified C symbol as the symcall request handler", uwsgi_opt_set_str, &usym.symcall_function_name, 0}, + {"symcall-register-rpc", required_argument, 0, "load the specified C symbol as an RPC function (syntax: name function)", uwsgi_opt_add_string_list, &usym.rpc, 0}, + {0, 0, 0, 0}, +}; + +static void uwsgi_symcall_init(){ + if (usym.symcall_function_name) { + usym.symcall_function = dlsym(RTLD_DEFAULT, usym.symcall_function_name); + if (!usym.symcall_function) { + uwsgi_log("unable to find symbol \"%s\" in process address space\n", usym.symcall_function_name); + exit(1); + } + uwsgi_log("symcall function ptr: %p\n", usym.symcall_function); + } + + struct uwsgi_string_list *usl = usym.rpc; + while(usl) { + char *space = strchr(usl->value, ' '); + if (!space) { + uwsgi_log("invalid symcall RPC syntax, must be: rpcname symbol\n"); + exit(1); + } + *space = 0; + void *func = dlsym(RTLD_DEFAULT, space+1); + if (!func) { + uwsgi_log("unable to find symbol \"%s\" in process address space\n", space+1); + exit(1); + } + if (uwsgi_register_rpc(usl->value, symcall_plugin.modifier1, 0, func)) { + uwsgi_log("unable to register rpc function"); + exit(1); + } + *space = ' '; + usl = usl->next; + } } -int uwsgi_symcall_request(struct wsgi_request *wsgi_req) { - - return symcall_function(wsgi_req); - +static int uwsgi_symcall_request(struct wsgi_request *wsgi_req) { + if (usym.symcall_function) { + return usym.symcall_function(wsgi_req); + } + return UWSGI_OK; } -void uwsgi_symcall_after_request(struct wsgi_request *wsgi_req) { - // TODO +static void uwsgi_symcall_after_request(struct wsgi_request *wsgi_req) { + log_request(wsgi_req); } +static uint16_t uwsgi_symcall_rpc(void *func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) { + uint16_t (*casted_func)(uint8_t, char **, uint16_t *, char *) = (uint16_t (*)(uint8_t, char **, uint16_t *, char *)) func; + return casted_func(argc, argv, argvs, buffer); +} struct uwsgi_plugin symcall_plugin = { .name = "symcall", .modifier1 = 18, - .init = uwsgi_symcall_init, + .options = uwsgi_symcall_options, + .init_apps = uwsgi_symcall_init, .request = uwsgi_symcall_request, .after_request = uwsgi_symcall_after_request, + .rpc = uwsgi_symcall_rpc, };