LCOV - code coverage report
Current view: top level - console/logstorage - dlt-logstorage-ctrl.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 23.1 % 186 43
Test Date: 2025-03-25 20:53:42 Functions: 30.8 % 13 4

            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 2.0-1