X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fmain.c;h=4dc6cb81b2a6dd6f60f3eea0948aa431b5025965;hb=d69860c79a93845b78bbeafafbf04d12c60e63fa;hp=05805e2dad27989080519d534b4a7eabc2158189;hpb=f5ce0df45f5ce9f0b57b250dfd44513d085f1e54;p=src%2Fapp-framework-binder.git diff --git a/src/main.c b/src/main.c index 05805e2d..4dc6cb81 100644 --- a/src/main.c +++ b/src/main.c @@ -27,6 +27,8 @@ #include #include +#include + #include #include @@ -41,8 +43,8 @@ #include "afb-hsrv.h" #include "afb-context.h" #include "afb-hreq.h" -#include "afb-sig-handler.h" -#include "afb-thread.h" +#include "afb-xreq.h" +#include "jobs.h" #include "afb-session.h" #include "verbose.h" #include "afb-common.h" @@ -100,11 +102,49 @@ static void start_list(struct afb_config_list *list, +--------------------------------------------------------- */ static void exit_handler() { - /* TODO: check whether using SIGHUP isn't better */ + struct sigaction siga; + + memset(&siga, 0, sizeof siga); + siga.sa_handler = SIG_IGN; + sigaction(SIGTERM, &siga, NULL); + if (SELF_PGROUP) - killpg(0, SIGKILL); + killpg(0, SIGTERM); else if (childpid > 0) - killpg(childpid, SIGKILL); + killpg(childpid, SIGTERM); +} + +static void on_sigterm(int signum, siginfo_t *info, void *uctx) +{ + NOTICE("Received SIGTERM"); + exit(0); +} + +static void on_sighup(int signum, siginfo_t *info, void *uctx) +{ + NOTICE("Received SIGHUP"); + /* TODO */ +} + +static void setup_daemon() +{ + struct sigaction siga; + + /* install signal handlers */ + memset(&siga, 0, sizeof siga); + siga.sa_flags = SA_SIGINFO; + + siga.sa_sigaction = on_sigterm; + sigaction(SIGTERM, &siga, NULL); + + siga.sa_sigaction = on_sighup; + sigaction(SIGHUP, &siga, NULL); + + /* handle groups */ + atexit(exit_handler); + + /* ignore any SIGPIPE */ + signal(SIGPIPE, SIG_IGN); } /*---------------------------------------------------------- @@ -223,7 +263,7 @@ static struct afb_hsrv *start_http_server() } NOTICE("Waiting port=%d rootdir=%s", config->httpdPort, config->rootdir); - NOTICE("Browser URL= http:/*localhost:%d", config->httpdPort); + NOTICE("Browser URL= http://localhost:%d", config->httpdPort); rc = afb_hsrv_start(hsrv, (uint16_t) config->httpdPort, 15); if (!rc) { @@ -394,74 +434,188 @@ static int execute_command() } /*--------------------------------------------------------- - | main - | Parse option and launch action + | startup calls +--------------------------------------------------------- */ -int main(int argc, char *argv[]) +struct startup_req { - struct afb_hsrv *hsrv; - struct sd_event *eventloop; + struct afb_xreq xreq; + char *api; + char *verb; + struct afb_config_list *current; + struct afb_session *session; +}; + +static void startup_call_reply(struct afb_xreq *xreq, int iserror, struct json_object *obj) +{ + struct startup_req *sreq = CONTAINER_OF_XREQ(struct startup_req, xreq); - LOGAUTH("afb-daemon"); + if (!iserror) + NOTICE("startup call %s returned %s", sreq->current->value, json_object_get_string(obj)); + else { + ERROR("startup call %s ERROR! %s", sreq->current->value, json_object_get_string(obj)); + exit(1); + } +} - sd_fds_init(); +static void startup_call_current(struct startup_req *sreq); - // ------------- Build session handler & init config ------- - config = afb_config_parse_arguments(argc, argv); - atexit(exit_handler); +static void startup_call_unref(struct afb_xreq *xreq) +{ + struct startup_req *sreq = CONTAINER_OF_XREQ(struct startup_req, xreq); + + free(sreq->api); + free(sreq->verb); + json_object_put(sreq->xreq.json); + sreq->current = sreq->current->next; + if (sreq->current) + startup_call_current(sreq); + else { + afb_session_close(sreq->session); + afb_session_unref(sreq->session); + free(sreq); + } +} + +static struct afb_xreq_query_itf startup_xreq_itf = +{ + .reply = startup_call_reply, + .unref = startup_call_unref +}; + +static void startup_call_current(struct startup_req *sreq) +{ + char *api, *verb, *json; + + api = sreq->current->value; + verb = strchr(api, '/'); + if (verb) { + json = strchr(verb, ':'); + if (json) { + memset(&sreq->xreq, 0, sizeof sreq->xreq); + afb_xreq_init(&sreq->xreq, &startup_xreq_itf); + afb_context_init(&sreq->xreq.context, sreq->session, NULL); + sreq->xreq.context.validated = 1; + sreq->api = strndup(api, verb - api); + sreq->verb = strndup(verb + 1, json - verb - 1); + sreq->xreq.api = sreq->api; + sreq->xreq.verb = sreq->verb; + sreq->xreq.json = json_tokener_parse(json + 1); + if (sreq->api && sreq->verb && sreq->xreq.json) { + afb_apis_call(&sreq->xreq); + afb_xreq_unref(&sreq->xreq); + return; + } + } + } + ERROR("Bad call specification %s", sreq->current->value); + exit(1); +} + +static void run_startup_calls() +{ + struct afb_config_list *list; + struct startup_req *sreq; + + list = config->calls; + if (list) { + sreq = calloc(1, sizeof *sreq); + sreq->session = afb_session_create("startup", 3600); + sreq->current = list; + startup_call_current(sreq); + } +} + +/*--------------------------------------------------------- + | job for starting the daemon + +--------------------------------------------------------- */ + +static void start() +{ + struct afb_hsrv *hsrv; // ------------------ sanity check ---------------------------------------- if (config->httpdPort <= 0) { ERROR("no port is defined"); - exit(1); + goto error; } + /* set the directories */ mkdir(config->workdir, S_IRWXU | S_IRGRP | S_IXGRP); if (chdir(config->workdir) < 0) { ERROR("Can't enter working dir %s", config->workdir); - exit(1); + goto error; + } + if (afb_common_rootdir_set(config->rootdir) < 0) { + ERROR("failed to set common root directory"); + goto error; } - afb_api_so_set_timeout(config->apiTimeout); + /* configure the daemon */ + afb_apis_set_timeout(config->apiTimeout); + afb_session_init(config->nbSessionMax, config->cntxTimeout, config->token); + if (!afb_hreq_init_cookie(config->httpdPort, config->rootapi, config->cntxTimeout)) { + ERROR("initialisation of cookies failed"); + goto error; + } + + /* install hooks */ + if (config->tracereq) + afb_hook_create_xreq(NULL, NULL, NULL, config->tracereq, NULL, NULL); + if (config->traceditf) + afb_hook_create_ditf(NULL, config->traceditf, NULL, NULL); + + /* load bindings */ start_list(config->dbus_clients, afb_api_dbus_add_client, "the afb-dbus client"); start_list(config->ws_clients, afb_api_ws_add_client, "the afb-websocket client"); start_list(config->ldpaths, afb_api_so_add_pathset, "the binding path set"); start_list(config->so_bindings, afb_api_so_add_binding, "the binding"); - afb_session_init(config->nbSessionMax, config->cntxTimeout, config->token, afb_apis_count()); - start_list(config->dbus_servers, afb_api_dbus_add_server, "the afb-dbus service"); start_list(config->ws_servers, afb_api_ws_add_server, "the afb-websocket service"); - if (!afb_hreq_init_cookie(config->httpdPort, config->rootapi, config->cntxTimeout)) { - ERROR("initialisation of cookies failed"); - exit(1); - } + DEBUG("Init config done"); - if (afb_sig_handler_init() < 0) { - ERROR("failed to initialise signal handlers"); - return 1; - } + /* start the services */ + if (afb_apis_start_all_services(1) < 0) + goto error; - // set the root dir - if (afb_common_rootdir_set(config->rootdir) < 0) { - ERROR("failed to set common root directory"); - return 1; + /* start the HTTP server */ + if (!config->noHttpd) { + hsrv = start_http_server(); + if (hsrv == NULL) + goto error; } - if (afb_thread_init(3, 1, 20) < 0) { - ERROR("failed to initialise threading"); - return 1; - } + /* run the command */ + if (execute_command() < 0) + goto error; + + /* ready */ + sd_notify(1, "READY=1"); + + /* run the startup calls */ + run_startup_calls(); + return; +error: + exit(1); +} + +/*--------------------------------------------------------- + | main + | Parse option and launch action + +--------------------------------------------------------- */ + +int main(int argc, char *argv[]) +{ // let's run this program with a low priority nice(20); - // ------------------ Finaly Process Commands ----------------------------- - // let's not take the risk to run as ROOT - //if (getuid() == 0) goto errorNoRoot; + sd_fds_init(); - DEBUG("Init config done"); + // ------------- Build session handler & init config ------- + config = afb_config_parse_arguments(argc, argv); + INFO("running with pid %d", getpid()); // --------- run ----------- if (config->background) { @@ -473,42 +627,12 @@ int main(int argc, char *argv[]) INFO("entering foreground mode"); } - /* ignore any SIGPIPE */ - signal(SIGPIPE, SIG_IGN); - - /* install trace of requests */ - if (config->tracereq) - afb_hook_req_create(NULL, NULL, NULL, config->tracereq, NULL, NULL); - - /* start the services */ - if (afb_apis_start_all_services(1) < 0) - exit(1); - - /* start the HTTP server */ - if (!config->noHttpd) { - hsrv = start_http_server(); - if (hsrv == NULL) - exit(1); - } - - /* run the command */ - if (execute_command() < 0) - exit(1); + /* set the daemon environment */ + setup_daemon(); - /* signal that ready */ - if (config->readyfd != 0) { - static const char readystr[] = "READY=1"; - write(config->readyfd, readystr, sizeof(readystr) - 1); - close(config->readyfd); - } - - // infinite loop - eventloop = afb_common_get_event_loop(); - sd_notify(1, "READY=1"); - for (;;) - sd_event_run(eventloop, 30000000); - - WARNING("hoops returned from infinite loop [report bug]"); - - return 0; + /* enter job processing */ + jobs_start(3, 0, 50, start); + WARNING("hoops returned from jobs_enter! [report bug]"); + return 1; } +