LCOV - code coverage report
Current view: top level - console/logstorage - dlt-logstorage-ctrl.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 43 186 23.1 %
Date: 2024-11-20 10:17:27 Functions: 4 13 30.8 %

          Line data    Source code
       1             : /**
       2             :  * Copyright (C) 2013 - 2015  Advanced Driver Information Technology.
       3             :  * This code is developed by Advanced Driver Information Technology.
       4             :  * Copyright of Advanced Driver Information Technology, Bosch and DENSO. *
       5             :  * This file is part of COVESA Project Dlt - Diagnostic Log and Trace console apps.
       6             :  *
       7             :  *
       8             :  * \copyright
       9             :  * This Source Code Form is subject to the terms of the
      10             :  * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
      11             :  * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      12             :  *
      13             :  *
      14             :  * \author Syed Hameed <shameed@jp.adit-jv.com> ADIT 2013 - 2015
      15             :  * \author Christoph Lipka <clipka@jp.adit-jv.com> ADIT 2015
      16             :  * \author Frederic Berat <fberat@de.adit-jv.com> ADIT 2015
      17             :  *
      18             :  * \file dlt-logstorage-ctrl.c
      19             :  * For further information see http://www.covesa.org/.
      20             :  */
      21             : /*******************************************************************************
      22             : **                                                                            **
      23             : **  SRC-MODULE: dlt-logstorage-ctrl.c                                         **
      24             : **                                                                            **
      25             : **  TARGET    : linux                                                         **
      26             : **                                                                            **
      27             : **  PROJECT   : DLT                                                           **
      28             : **                                                                            **
      29             : **  AUTHOR    : Syed Hameed shameed@jp.adit-jv.com                            **
      30             : **              Christoph Lipka clipka@jp.adit-jv.com                         **
      31             : **              AnithaAmmaji.baggam@in.bosch.com                              **
      32             : **              Frederic Berat fberat@de.adit-jv.com                          **
      33             : **  PURPOSE   :                                                               **
      34             : **                                                                            **
      35             : **  REMARKS   :                                                               **
      36             : **                                                                            **
      37             : **  PLATFORM DEPENDANT [yes/no]: yes                                          **
      38             : **                                                                            **
      39             : **  TO BE CHANGED BY USER [yes/no]: no                                        **
      40             : **                                                                            **
      41             : *******************************************************************************/
      42             : 
      43             : /*******************************************************************************
      44             : **                      Author Identity                                       **
      45             : ********************************************************************************
      46             : ** Initials     Name                       Company                            **
      47             : ** --------     -------------------------  ---------------------------------- **
      48             : **  sh          Syed Hameed                ADIT                               **
      49             : **  cl          Christoph Lipka            ADIT                               **
      50             : **  BA          Anitha BA                  ADIT                               **
      51             : **  fb          Frederic Berat             ADIT                               **
      52             : *******************************************************************************/
      53             : 
      54             : #define pr_fmt(fmt) "Logstorage control: "fmt
      55             : 
      56             : #include <ctype.h>
      57             : #include <errno.h>
      58             : #include <stdio.h>
      59             : #include <stdlib.h>
      60             : #include <signal.h>
      61             : #include <string.h>
      62             : #include <getopt.h>
      63             : 
      64             : #include <poll.h>
      65             : 
      66             : #if defined(__linux__)
      67             : #   include "sd-daemon.h"
      68             : #endif
      69             : 
      70             : #include "dlt_protocol.h"
      71             : #include "dlt_client.h"
      72             : #include "dlt-control-common.h"
      73             : #include "dlt-logstorage-common.h"
      74             : #include "dlt-logstorage-ctrl.h"
      75             : 
      76             : #define POLL_TIME_OUT   500
      77             : #define EV_MASK_REJECTED (POLLERR | POLLHUP | POLLNVAL)
      78             : 
      79             : #define DLT_LOGSTORAGE_CTRL_EXIT 1
      80             : static int must_exit;
      81             : struct dlt_event {
      82             :     struct pollfd pfd;
      83             :     void *func;
      84             : };
      85             : 
      86             : /** @brief Triggers the application exit
      87             :  *
      88             :  * The application will exit on next poll timeout.
      89             :  */
      90           0 : void dlt_logstorage_exit(void)
      91             : {
      92           0 :     must_exit = DLT_LOGSTORAGE_CTRL_EXIT;
      93           0 : }
      94             : 
      95             : /** @brief Check if the application must exit
      96             :  *
      97             :  * The application will exit on next poll timeout.
      98             :  */
      99           0 : int dlt_logstorage_must_exit(void)
     100             : {
     101           0 :     return must_exit;
     102             : }
     103             : 
     104             : /** @brief Signal handler.
     105             :  *
     106             :  * Triggers the exit of the application in case of specific signals
     107             :  *
     108             :  * @param signo The value of the signal received.
     109             :  */
     110           0 : static void catch_signal(int signo)
     111             : {
     112           0 :     if (signo) {
     113           0 :         pr_error("Signal %d received, exiting.", signo);
     114             :         dlt_logstorage_exit();
     115             :     }
     116           0 : }
     117             : 
     118             : /** @brief Install a handler for some signals
     119             :  *
     120             :  * Handler are installed on exit related signals. That allows to exit from
     121             :  * the main loop gracefully.
     122             :  */
     123           0 : static void install_signal_handler(void)
     124             : {
     125           0 :     int signals[] = { SIGINT, SIGQUIT, SIGTERM, 0 };
     126             :     unsigned int i;
     127             :     struct sigaction sa;
     128             : 
     129           0 :     pr_verbose("Installing signal handler.\n");
     130             : 
     131             :     /* install a signal handler for the above listed signals */
     132           0 :     for (i = 0; signals[i]; i++) {
     133             :         memset(&sa, 0, sizeof(sa));
     134           0 :         sa.sa_handler = catch_signal;
     135             : 
     136           0 :         if (sigaction(signals[i], &sa, NULL) < 0)
     137           0 :             pr_error("Failed to install signal %u handler. Error: %s\n",
     138             :                      signals[i], strerror(errno));
     139             :     }
     140           0 : }
     141             : 
     142             : #define MAX_RESPONSE_LENGTH 32
     143             : /** @brief Analyze the daemon answer to a request
     144             :  *
     145             :  * This function checks whether if the daemon answered positively to
     146             :  * the request or not.
     147             :  *
     148             :  * @param data    The textual answer
     149             :  * @param payload The answer payload
     150             :  * @param len     The answer payload length
     151             :  * @return 0 on success, -1 otherwise.
     152             :  */
     153           2 : static int analyze_response(char *data, void *payload, int len)
     154             : {
     155             :     int ret = -1;
     156           2 :     char resp_ok[MAX_RESPONSE_LENGTH] = { 0 };
     157           2 :     char resp_warning[MAX_RESPONSE_LENGTH] = { 0 };
     158           2 :     char resp_perm_denied[MAX_RESPONSE_LENGTH] = { 0 };
     159             : 
     160           2 :     if ((data == NULL) || (payload == NULL))
     161             :         return -1;
     162             : 
     163             :     /* satisfy compiler */
     164             :     (void)payload;
     165             :     (void)len;
     166             : 
     167             :     snprintf(resp_ok,
     168             :              MAX_RESPONSE_LENGTH,
     169             :              "service(%d), ok",
     170             :              DLT_SERVICE_ID_OFFLINE_LOGSTORAGE);
     171             : 
     172             :     snprintf(resp_warning,
     173             :              MAX_RESPONSE_LENGTH,
     174             :              "service(%d), warning",
     175             :              DLT_SERVICE_ID_OFFLINE_LOGSTORAGE);
     176             : 
     177             :     snprintf(resp_perm_denied,
     178             :              MAX_RESPONSE_LENGTH,
     179             :              "service(%d), perm_denied",
     180             :              DLT_SERVICE_ID_OFFLINE_LOGSTORAGE);
     181             : 
     182           2 :     if (strncmp(data, resp_ok, strlen(resp_ok)) == 0)
     183             :         ret = 0;
     184             : 
     185           2 :     if (strncmp(data, resp_warning, strlen(resp_warning)) == 0) {
     186           0 :         pr_error("Warning:Some filter configurations are ignored due to configuration issues \n");
     187             :         ret = 0;
     188             :     }
     189             : 
     190           2 :     if (strncmp(data, resp_perm_denied, strlen(resp_perm_denied)) == 0) {
     191           0 :         pr_error("Warning: Permission denied.\n");
     192             :         ret = 0;
     193             :     }
     194             : 
     195           2 :     pr_verbose("Response received: '%s'\n", data);
     196           2 :     pr_verbose("Response expected: '%s'\n", resp_ok);
     197             : 
     198             :     return ret;
     199             : }
     200             : 
     201             : /** @brief Add a new event to watch
     202             :  *
     203             :  * This function could be exported to be used by udev/prop so that they can
     204             :  * register several events.
     205             :  *
     206             :  * @param ev_hdl The structure containing the file descriptors
     207             :  * @param fd The file descriptor to watch
     208             :  * @param cb The callback to be called on event.
     209             :  *
     210             :  * @return 0 on success, -1 if the parameters are invalid.
     211             :  */
     212           0 : static int dlt_logstorage_ctrl_add_event(struct dlt_event *ev_hdl,
     213             :                                          int fd,
     214             :                                          void *cb)
     215             : {
     216           0 :     if ((fd < 0) || !cb || !ev_hdl) {
     217           0 :         pr_error("Wrong parameter to add event (%d %p)\n", fd, cb);
     218           0 :         return -1;
     219             :     }
     220             : 
     221           0 :     pr_verbose("Setting up the event handler with (%d, %p).\n", fd, cb);
     222             : 
     223           0 :     ev_hdl->func = cb;
     224           0 :     ev_hdl->pfd.fd = fd;
     225             : 
     226           0 :     return 0;
     227             : }
     228             : 
     229             : /** @brief Main execution loop
     230             :  *
     231             :  * Waits on events, and executes the callbacks retrieved
     232             :  * back from the event structure.
     233             :  *
     234             :  * @return 0 on success, -1 otherwise.
     235             :  */
     236           0 : static int dlt_logstorage_ctrl_execute_event_loop(struct dlt_event *ev)
     237             : {
     238             :     int ret = 0;
     239           0 :     int (*callback)() = ev->func;
     240             : 
     241           0 :     ret = poll(&ev->pfd, 1, POLL_TIME_OUT);
     242             : 
     243           0 :     if (ret <= 0) {
     244           0 :         if (errno == EINTR)
     245             :             ret = 0;
     246             : 
     247           0 :         if (ret < 0)
     248           0 :             pr_error("poll error: %s\n", strerror(errno));
     249             : 
     250           0 :         return ret;
     251             :     }
     252             : 
     253           0 :     if (ev->pfd.revents == 0)
     254             :         return 0;
     255             : 
     256           0 :     if (ev->pfd.events & EV_MASK_REJECTED) {
     257           0 :         pr_error("Error while polling. Event received: 0x%x\n", ev->pfd.events);
     258             :         /* We only support one event producer.
     259             :          * Error means that this producer died.
     260             :          */
     261           0 :         pr_error("Now closing fd and exiting.\n");
     262           0 :         close(ev->pfd.fd);
     263           0 :         ev->pfd.fd = -1;
     264             :         dlt_logstorage_exit();
     265           0 :         return -1;
     266             :     }
     267             : 
     268           0 :     if (!callback) {
     269           0 :         pr_error("Callback not found, exiting.\n");
     270             :         dlt_logstorage_exit();
     271           0 :         return -1;
     272             :     }
     273             : 
     274           0 :     pr_verbose("Got new event, calling %p.\n", callback);
     275             : 
     276           0 :     if (callback() < 0) {
     277           0 :         pr_error("Error while calling the callback, exiting.\n");
     278             :         dlt_logstorage_exit();
     279           0 :         return -1;
     280             :     }
     281             : 
     282             :     return 0;
     283             : }
     284             : 
     285             : /** @brief Start event loop and receive messages from DLT.
     286             :  *
     287             :  * The function will first install the signal handler,
     288             :  * then create the poll instance, initialize the communication controller,
     289             :  * initialize the event handler and finally start the polling.
     290             :  *
     291             :  * @return 0 on success, -1 on error
     292             :  */
     293           0 : static int dlt_logstorage_ctrl_setup_event_loop(void)
     294             : {
     295             :     int ret = 0;
     296           0 :     struct dlt_event ev_hdl = {
     297             :         .pfd = {
     298             :             .fd = -1,
     299             :             .events = POLLIN
     300             :         }
     301             :     };
     302             : 
     303           0 :     install_signal_handler();
     304             : 
     305           0 :     pr_verbose("Creating poll instance.\n");
     306             : 
     307             :     /* Initializing the communication with the daemon */
     308           0 :     while (dlt_control_init(analyze_response, get_ecuid(), get_verbosity()) &&
     309             :            !dlt_logstorage_must_exit()) {
     310           0 :         pr_error("Failed to initialize connection with the daemon.\n");
     311           0 :         pr_error("Retrying to connect in %ds.\n", get_timeout());
     312           0 :         sleep((unsigned int) get_timeout());
     313             :     }
     314             : 
     315           0 :     if (dlt_logstorage_must_exit()) {
     316           0 :         pr_verbose("Exiting.\n");
     317           0 :         return 0;
     318             :     }
     319             : 
     320           0 :     pr_verbose("Initializing event generator.\n");
     321             : 
     322           0 :     if (dlt_logstorage_init_handler() < 0) {
     323           0 :         pr_error("Failed to initialize handler.\n");
     324           0 :         dlt_control_deinit();
     325           0 :         return -1;
     326             :     }
     327             : 
     328           0 :     if (dlt_logstorage_ctrl_add_event(&ev_hdl,
     329             :                                       dlt_logstorage_get_handler_fd(),
     330             :                                       dlt_logstorage_get_handler_cb()) < 0) {
     331           0 :         pr_error("add_event error: %s\n", strerror(errno));
     332             :         dlt_logstorage_exit();
     333             :     }
     334             : 
     335           0 :     while (!dlt_logstorage_must_exit() && (ret == 0))
     336           0 :         ret = dlt_logstorage_ctrl_execute_event_loop(&ev_hdl);
     337             : 
     338             :     /* Clean up */
     339           0 :     dlt_logstorage_deinit_handler();
     340           0 :     dlt_control_deinit();
     341             : 
     342           0 :     return ret;
     343             : }
     344             : 
     345             : /** @brief Send a single command to DLT daemon and wait for response
     346             :  *
     347             :  * @return 0 on success, -1 otherwise.
     348             :  */
     349           2 : static int dlt_logstorage_ctrl_single_request()
     350             : {
     351             :     int ret = 0;
     352             : 
     353             :     /* in case sync all caches, an empty path is given */
     354           2 :     if (get_default_event_type() != EVENT_SYNC_CACHE) {
     355             :         /* Check if a 'CONF_NAME' file is present at the given path */
     356           0 :         if (!dlt_logstorage_check_config_file(get_default_path())) {
     357           0 :             pr_error("No '%s' file available at: %s\n",
     358             :                      CONF_NAME,
     359             :                      get_default_path());
     360           0 :             return -1;
     361             :         }
     362             : 
     363           0 :         if (!dlt_logstorage_check_directory_permission(get_default_path())) {
     364           0 :             pr_error("'%s' is not writable\n", get_default_path());
     365           0 :             return -1;
     366             :         }
     367             :     }
     368             : 
     369             :     /* Initializing the communication with the daemon */
     370           2 :     while (dlt_control_init(analyze_response, get_ecuid(), get_verbosity()) &&
     371             :            !dlt_logstorage_must_exit()) {
     372           0 :         pr_error("Failed to initialize connection with the daemon.\n");
     373           0 :         pr_error("Retrying to connect in %ds.\n", get_timeout());
     374           0 :         sleep( (unsigned int) get_timeout());
     375             :     }
     376             : 
     377           2 :     pr_verbose("event type is [%d]\t device path is [%s]\n",
     378             :                get_default_event_type(),
     379             :                get_default_path());
     380             : 
     381           2 :     ret = dlt_logstorage_send_event(get_default_event_type(),
     382             :                                     get_default_path());
     383             : 
     384           2 :     dlt_control_deinit();
     385             : 
     386           2 :     return ret;
     387             : }
     388             : 
     389             : /** @brief Print out the application help
     390             :  */
     391           0 : static void usage(void)
     392             : {
     393             :     printf("Usage: dlt-logstorage-ctrl [options]\n");
     394             :     printf("Send a trigger to DLT daemon to connect/disconnect"
     395             :            "a certain logstorage device\n");
     396             :     printf("\n");
     397             :     printf("Options:\n");
     398             :     printf("  -c --command               Connection type: connect = 1, disconnect = 0\n");
     399             :     printf("  -d[prop] --daemonize=prop  Run as daemon: prop = use proprietary handler\n");
     400             :     printf("                             'prop' may be replaced by any meaningful word\n");
     401             :     printf("                             If prop is not specified, udev will be used\n");
     402             :     printf("  -e --ecuid                 Set ECU ID (Default: %s)\n", DLT_CTRL_DEFAULT_ECUID);
     403             :     printf("  -h --help                  Usage\n");
     404             :     printf("  -p --path                  Mount point path\n");
     405             :     printf("  -s[path] --snapshot=path   Sync Logstorage cache\n");
     406             :     printf("                             Don't use -s together with -d and -c\n");
     407             :     printf("  -t                         Specify connection timeout (Default: %ds)\n",
     408             :            DLT_CTRL_TIMEOUT);
     409             :     printf("  -S --send-header           Send message with serial header (Default: Without serial header)\n");
     410             :     printf("  -R --resync-header         Enable resync serial header\n");
     411           0 :     printf("  -v --verbose               Set verbose flag (Default:%d)\n", get_verbosity());
     412             :     printf("  -C filename                DLT daemon configuration file (Default: " CONFIGURATION_FILES_DIR
     413             :            "/dlt.conf)\n");
     414           0 : }
     415             : 
     416             : static struct option long_options[] = {
     417             :     {"command",       required_argument,  0,  'c'},
     418             :     {"daemonize",     optional_argument,  0,  'd'},
     419             :     {"ecuid",         required_argument,  0,  'e'},
     420             :     {"help",          no_argument,        0,  'h'},
     421             :     {"path",          required_argument,  0,  'p'},
     422             :     {"snapshot",      optional_argument,  0,  's'},
     423             :     {"timeout",       required_argument,  0,  't'},
     424             :     {"send-header",   no_argument,        0,  'S'},
     425             :     {"resync-header", no_argument,        0,  'R'},
     426             :     {"verbose",       no_argument,        0,  'v'},
     427             :     {0,               0,                  0,  0}
     428             : };
     429             : 
     430             : /** @brief Parses the application arguments
     431             :  *
     432             :  * The arguments are parsed and saved in static structure for future use.
     433             :  *
     434             :  * @param argc The amount of arguments
     435             :  * @param argv The table of arguments
     436             :  *
     437             :  * @return 0 on success, -1 otherwise
     438             :  */
     439           2 : static int parse_args(int argc, char *argv[])
     440             : {
     441             :     int c = -1;
     442           2 :     int long_index = 0;
     443             : 
     444           6 :     while ((c = getopt_long(argc,
     445             :                             argv,
     446             :                             ":s::t:hSRe:p:d::c:vC:",
     447             :                             long_options,
     448           6 :                             &long_index)) != -1)
     449           4 :         switch (c) {
     450           2 :         case 's':
     451           2 :             set_default_event_type(EVENT_SYNC_CACHE);
     452             : 
     453           2 :             if ((optarg != NULL) && (strlen(optarg) >= DLT_MOUNT_PATH_MAX)) {
     454           0 :                 pr_error("Mount path '%s' too long\n", optarg);
     455           0 :                 return -1;
     456             :             }
     457             : 
     458           2 :             set_default_path(optarg);
     459           2 :             break;
     460           0 :         case 't':
     461           0 :             if (optarg != NULL)
     462           0 :                 set_timeout((int) strtol(optarg, NULL, 10));
     463             :             break;
     464           0 :         case 'S':
     465             :         {
     466           0 :             set_send_serial_header(1);
     467           0 :             break;
     468             :         }
     469           0 :         case 'R':
     470             :         {
     471           0 :             set_resync_serial_header(1);
     472           0 :             break;
     473             :         }
     474           0 :         case 'h':
     475           0 :             usage();
     476           0 :             return -1;
     477           0 :         case 'e':
     478           0 :             set_ecuid(optarg);
     479           0 :             break;
     480           0 :         case 'd':
     481           0 :             pr_verbose("Choosing handler.\n");
     482           0 :             set_handler_type(optarg);
     483           0 :             pr_verbose("Handler chosen: %d.\n", get_handler_type());
     484             :             break;
     485           0 :         case 'p':
     486             : 
     487           0 :             if ((optarg != NULL) && (strlen(optarg) >= DLT_MOUNT_PATH_MAX)) {
     488           0 :                 pr_error("Mount path '%s' too long\n", optarg);
     489           0 :                 return -1;
     490             :             }
     491             : 
     492           0 :             set_default_path(optarg);
     493           0 :             break;
     494           0 :         case 'c':
     495           0 :             if (optarg != NULL)
     496           0 :                 set_default_event_type(strtol(optarg, NULL, 10));
     497             :             break;
     498           0 :         case 'v':
     499           0 :             set_verbosity(1);
     500           0 :             pr_verbose("Now in verbose mode.\n");
     501             :             break;
     502           2 :         case 'C':
     503           2 :             set_conf(optarg);
     504           2 :             pr_verbose("Set %s to read options\n", optarg);
     505             :             break;
     506           0 :         case ':':
     507           0 :             pr_error("Option -%c requires an argument.\n", optopt);
     508           0 :             usage();
     509           0 :             return -1;
     510           0 :         case '?':
     511             : 
     512           0 :             if (isprint(optopt))
     513           0 :                 pr_error("Unknown option -%c.\n", optopt);
     514             :             else
     515           0 :                 pr_error("Unknown option character \\x%x.\n", optopt);
     516             : 
     517           0 :             usage();
     518           0 :             return -1;
     519           0 :         default:
     520           0 :             pr_error("Try %s -h for more information.\n", argv[0]);
     521           0 :             return -1;
     522             :         }
     523             : 
     524             : 
     525             : 
     526           4 :     if ((get_default_event_type() == EVENT_SYNC_CACHE) &&
     527           2 :         (get_handler_type() != CTRL_NOHANDLER)) {
     528           0 :         pr_error("Sync caches not available in daemon mode\n");
     529           0 :         return -1;
     530             :     }
     531             : 
     532             :     /* Retrieve ECUID from dlt.conf */
     533           2 :     if (get_ecuid() == NULL)
     534           0 :         set_ecuid(NULL);
     535             : 
     536             :     return 0;
     537             : }
     538             : 
     539             : #if !defined(DLT_SYSTEMD_ENABLE)
     540           0 : int sd_notify(int unset_environment, const char *state)
     541             : {
     542             :     /* Satisfy Compiler for warnings */
     543             :     (void)unset_environment;
     544             :     (void)state;
     545           0 :     return 0;
     546             : }
     547             : #endif
     548             : 
     549             : /** @brief Entry point
     550             :  *
     551             :  * Execute the argument parser and call the main feature accordingly.
     552             :  *
     553             :  * @param argc The amount of arguments
     554             :  * @param argv The table of arguments
     555             :  *
     556             :  * @return 0 on success, -1 otherwise
     557             :  */
     558           2 : int main(int argc, char *argv[])
     559             : {
     560             :     int ret = 0;
     561             : 
     562           2 :     set_timeout(DLT_CTRL_TIMEOUT);
     563           2 :     set_send_serial_header(0);
     564           2 :     set_resync_serial_header(0);
     565             : 
     566             :     /* Get command line arguments */
     567           2 :     if (parse_args(argc, argv) != 0)
     568             :         return -1;
     569             : 
     570             :     /* all parameter valid, start communication with daemon or setup
     571             :      * communication with control daemon */
     572           2 :     if (get_handler_type() == CTRL_NOHANDLER) {
     573           2 :         pr_verbose("One shot.\n");
     574             : 
     575           2 :         ret = dlt_logstorage_ctrl_single_request();
     576             : 
     577           2 :         if (ret < 0)
     578           0 :             pr_error("Message failed to be send. Please check DLT config.\n");
     579             :     }
     580             :     else {
     581           0 :         pr_verbose("Entering in daemon mode.\n");
     582             : 
     583             :         /* Let's daemonize */
     584             :         if (sd_notify(0, "READY=1") <= 0) {
     585           0 :             pr_verbose("SD notify failed, manually daemonizing.\n");
     586             : 
     587             :             /* No message can be sent or Systemd is not available.
     588             :              * Daemonizing manually.
     589             :              */
     590           0 :             if (daemon(1, 1)) {
     591           0 :                 pr_error("Failed to daemonize: %s\n", strerror(errno));
     592           0 :                 return EXIT_FAILURE;
     593             :             }
     594             :         }
     595             : 
     596           0 :         pr_verbose("Executing the event loop\n");
     597           0 :         ret = dlt_logstorage_ctrl_setup_event_loop();
     598             :     }
     599             : 
     600           2 :     pr_verbose("Exiting.\n");
     601             :     return ret;
     602             : }

Generated by: LCOV version 1.14