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.0 % 187 43
Test Date: 2025-12-12 09:13:23 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 one 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              :     union {
     240              :         void *ptr;
     241              :         int (*callback)(void);
     242              :     } callback_converter;
     243              :     int (*callback)(void);
     244              : 
     245            0 :     callback_converter.ptr = ev->func;
     246            0 :     callback = callback_converter.callback;
     247              : 
     248            0 :     ret = poll(&ev->pfd, 1, POLL_TIME_OUT);
     249              : 
     250            0 :     if (ret <= 0) {
     251            0 :         if (errno == EINTR)
     252              :             ret = 0;
     253              : 
     254            0 :         if (ret < 0)
     255            0 :             pr_error("poll error: %s\n", strerror(errno));
     256              : 
     257            0 :         return ret;
     258              :     }
     259              : 
     260            0 :     if (ev->pfd.revents == 0)
     261              :         return 0;
     262              : 
     263            0 :     if (ev->pfd.events & EV_MASK_REJECTED) {
     264            0 :         pr_error("Error while polling. Event received: 0x%x\n", ev->pfd.events);
     265              :         /* We only support one event producer.
     266              :          * Error means that this producer died.
     267              :          */
     268            0 :         pr_error("Now closing fd and exiting.\n");
     269            0 :         close(ev->pfd.fd);
     270            0 :         ev->pfd.fd = -1;
     271              :         dlt_logstorage_exit();
     272            0 :         return -1;
     273              :     }
     274              : 
     275            0 :     if (!callback) {
     276            0 :         pr_error("Callback not found, exiting.\n");
     277              :         dlt_logstorage_exit();
     278            0 :         return -1;
     279              :     }
     280              : 
     281              :     callback_converter.callback = callback;
     282            0 :     pr_verbose("Got new event, calling %p.\n", callback_converter.ptr);
     283              : 
     284            0 :     if (callback() < 0) {
     285            0 :         pr_error("Error while calling the callback, exiting.\n");
     286              :         dlt_logstorage_exit();
     287            0 :         return -1;
     288              :     }
     289              : 
     290              :     return 0;
     291              : }
     292              : 
     293              : /** @brief Start event loop and receive messages from DLT.
     294              :  *
     295              :  * The function will first install the signal handler,
     296              :  * then create the poll instance, initialize the communication controller,
     297              :  * initialize the event handler and finally start the polling.
     298              :  *
     299              :  * @return 0 on success, -1 on error
     300              :  */
     301            0 : static int dlt_logstorage_ctrl_setup_event_loop(void)
     302              : {
     303              :     int ret = 0;
     304            0 :     struct dlt_event ev_hdl = {
     305              :         .pfd = {
     306              :             .fd = -1,
     307              :             .events = POLLIN
     308              :         }
     309              :     };
     310              : 
     311            0 :     install_signal_handler();
     312              : 
     313            0 :     pr_verbose("Creating poll instance.\n");
     314              : 
     315              :     /* Initializing the communication with the daemon */
     316            0 :     while (dlt_control_init(analyze_response, get_ecuid(), get_verbosity()) &&
     317              :            !dlt_logstorage_must_exit()) {
     318            0 :         pr_error("Failed to initialize connection with the daemon.\n");
     319            0 :         pr_error("Retrying to connect in %ds.\n", get_timeout());
     320            0 :         sleep((unsigned int) get_timeout());
     321              :     }
     322              : 
     323            0 :     if (dlt_logstorage_must_exit()) {
     324            0 :         pr_verbose("Exiting.\n");
     325            0 :         return 0;
     326              :     }
     327              : 
     328            0 :     pr_verbose("Initializing event generator.\n");
     329              : 
     330            0 :     if (dlt_logstorage_init_handler() < 0) {
     331            0 :         pr_error("Failed to initialize handler.\n");
     332            0 :         dlt_control_deinit();
     333            0 :         return -1;
     334              :     }
     335              : 
     336            0 :     if (dlt_logstorage_ctrl_add_event(&ev_hdl,
     337              :                                       dlt_logstorage_get_handler_fd(),
     338              :                                       dlt_logstorage_get_handler_cb()) < 0) {
     339            0 :         pr_error("add_event error: %s\n", strerror(errno));
     340              :         dlt_logstorage_exit();
     341              :     }
     342              : 
     343            0 :     while (!dlt_logstorage_must_exit() && (ret == 0))
     344            0 :         ret = dlt_logstorage_ctrl_execute_event_loop(&ev_hdl);
     345              : 
     346              :     /* Clean up */
     347            0 :     dlt_logstorage_deinit_handler();
     348            0 :     dlt_control_deinit();
     349              : 
     350            0 :     return ret;
     351              : }
     352              : 
     353              : /** @brief Send a single command to DLT daemon and wait for response
     354              :  *
     355              :  * @return 0 on success, -1 otherwise.
     356              :  */
     357            2 : static int dlt_logstorage_ctrl_single_request()
     358              : {
     359              :     int ret = 0;
     360              : 
     361              :     /* in case sync all caches, an empty path is given */
     362            2 :     if (get_default_event_type() != EVENT_SYNC_CACHE) {
     363              :         /* Check if a 'CONF_NAME' file is present at the given path */
     364            0 :         if (!dlt_logstorage_check_config_file(get_default_path())) {
     365            0 :             pr_error("No '%s' file available at: %s\n",
     366              :                      CONF_NAME,
     367              :                      get_default_path());
     368            0 :             return -1;
     369              :         }
     370              : 
     371            0 :         if (!dlt_logstorage_check_directory_permission(get_default_path())) {
     372            0 :             pr_error("'%s' is not writable\n", get_default_path());
     373            0 :             return -1;
     374              :         }
     375              :     }
     376              : 
     377              :     /* Initializing the communication with the daemon */
     378            2 :     while (dlt_control_init(analyze_response, get_ecuid(), get_verbosity()) &&
     379              :            !dlt_logstorage_must_exit()) {
     380            0 :         pr_error("Failed to initialize connection with the daemon.\n");
     381            0 :         pr_error("Retrying to connect in %ds.\n", get_timeout());
     382            0 :         sleep( (unsigned int) get_timeout());
     383              :     }
     384              : 
     385            2 :     pr_verbose("event type is [%d]\t device path is [%s]\n",
     386              :                get_default_event_type(),
     387              :                get_default_path());
     388              : 
     389            2 :     ret = dlt_logstorage_send_event(get_default_event_type(),
     390              :                                     get_default_path());
     391              : 
     392            2 :     dlt_control_deinit();
     393              : 
     394            2 :     return ret;
     395              : }
     396              : 
     397              : /** @brief Print out the application help
     398              :  */
     399            0 : static void usage(void)
     400              : {
     401              :     printf("Usage: dlt-logstorage-ctrl [options]\n");
     402              :     printf("Send a trigger to DLT daemon to connect/disconnect"
     403              :            "a certain logstorage device\n");
     404              :     printf("\n");
     405              :     printf("Options:\n");
     406              :     printf("  -c --command               Connection type: connect = 1, disconnect = 0\n");
     407              :     printf("  -d[prop] --daemonize=prop  Run as daemon: prop = use proprietary handler\n");
     408              :     printf("                             'prop' may be replaced by any meaningful word\n");
     409              :     printf("                             If prop is not specified, udev will be used\n");
     410              :     printf("  -e --ecuid                 Set ECU ID (Default: %s)\n", DLT_CTRL_DEFAULT_ECUID);
     411              :     printf("  -h --help                  Usage\n");
     412              :     printf("  -p --path                  Mount point path\n");
     413              :     printf("  -s[path] --snapshot=path   Sync Logstorage cache\n");
     414              :     printf("                             Don't use -s together with -d and -c\n");
     415              :     printf("  -t                         Specify connection timeout (Default: %ds)\n",
     416              :            DLT_CTRL_TIMEOUT);
     417              :     printf("  -S --send-header           Send message with serial header (Default: Without serial header)\n");
     418              :     printf("  -R --resync-header         Enable resync serial header\n");
     419            0 :     printf("  -v --verbose               Set verbose flag (Default:%d)\n", get_verbosity());
     420              :     printf("  -C filename                DLT daemon configuration file (Default: " CONFIGURATION_FILES_DIR
     421              :            "/dlt.conf)\n");
     422            0 : }
     423              : 
     424              : static struct option long_options[] = {
     425              :     {"command",       required_argument,  0,  'c'},
     426              :     {"daemonize",     optional_argument,  0,  'd'},
     427              :     {"ecuid",         required_argument,  0,  'e'},
     428              :     {"help",          no_argument,        0,  'h'},
     429              :     {"path",          required_argument,  0,  'p'},
     430              :     {"snapshot",      optional_argument,  0,  's'},
     431              :     {"timeout",       required_argument,  0,  't'},
     432              :     {"send-header",   no_argument,        0,  'S'},
     433              :     {"resync-header", no_argument,        0,  'R'},
     434              :     {"verbose",       no_argument,        0,  'v'},
     435              :     {0,               0,                  0,  0}
     436              : };
     437              : 
     438              : /** @brief Parses the application arguments
     439              :  *
     440              :  * The arguments are parsed and saved in static structure for future use.
     441              :  *
     442              :  * @param argc The amount of arguments
     443              :  * @param argv The table of arguments
     444              :  *
     445              :  * @return 0 on success, -1 otherwise
     446              :  */
     447            2 : static int parse_args(int argc, char *argv[])
     448              : {
     449              :     int c = -1;
     450            2 :     int long_index = 0;
     451              : 
     452            6 :     while ((c = getopt_long(argc,
     453              :                             argv,
     454              :                             ":s::t:hSRe:p:d::c:vC:",
     455              :                             long_options,
     456            6 :                             &long_index)) != -1)
     457            4 :         switch (c) {
     458            2 :         case 's':
     459            2 :             set_default_event_type(EVENT_SYNC_CACHE);
     460              : 
     461            2 :             if ((optarg != NULL) && (strlen(optarg) >= DLT_MOUNT_PATH_MAX)) {
     462            0 :                 pr_error("Mount path '%s' too long\n", optarg);
     463            0 :                 return -1;
     464              :             }
     465              : 
     466            2 :             set_default_path(optarg);
     467            2 :             break;
     468            0 :         case 't':
     469            0 :             if (optarg != NULL)
     470            0 :                 set_timeout((int) strtol(optarg, NULL, 10));
     471              :             break;
     472            0 :         case 'S':
     473              :         {
     474            0 :             set_send_serial_header(1);
     475            0 :             break;
     476              :         }
     477            0 :         case 'R':
     478              :         {
     479            0 :             set_resync_serial_header(1);
     480            0 :             break;
     481              :         }
     482            0 :         case 'h':
     483            0 :             usage();
     484            0 :             return -1;
     485            0 :         case 'e':
     486            0 :             set_ecuid(optarg);
     487            0 :             break;
     488            0 :         case 'd':
     489            0 :             pr_verbose("Choosing handler.\n");
     490            0 :             set_handler_type(optarg);
     491            0 :             pr_verbose("Handler chosen: %d.\n", get_handler_type());
     492              :             break;
     493            0 :         case 'p':
     494              : 
     495            0 :             if ((optarg != NULL) && (strlen(optarg) >= DLT_MOUNT_PATH_MAX)) {
     496            0 :                 pr_error("Mount path '%s' too long\n", optarg);
     497            0 :                 return -1;
     498              :             }
     499              : 
     500            0 :             set_default_path(optarg);
     501            0 :             break;
     502            0 :         case 'c':
     503            0 :             if (optarg != NULL)
     504            0 :                 set_default_event_type(strtol(optarg, NULL, 10));
     505              :             break;
     506            0 :         case 'v':
     507            0 :             set_verbosity(1);
     508            0 :             pr_verbose("Now in verbose mode.\n");
     509              :             break;
     510            2 :         case 'C':
     511            2 :             set_conf(optarg);
     512            2 :             pr_verbose("Set %s to read options\n", optarg);
     513              :             break;
     514            0 :         case ':':
     515            0 :             pr_error("Option -%c requires an argument.\n", optopt);
     516            0 :             usage();
     517            0 :             return -1;
     518            0 :         case '?':
     519              : 
     520            0 :             if (isprint(optopt))
     521            0 :                 pr_error("Unknown option -%c.\n", optopt);
     522              :             else
     523            0 :                 pr_error("Unknown option character \\x%x.\n", optopt);
     524              : 
     525            0 :             usage();
     526            0 :             return -1;
     527            0 :         default:
     528            0 :             pr_error("Try %s -h for more information.\n", argv[0]);
     529            0 :             return -1;
     530              :         }
     531              : 
     532              : 
     533              : 
     534            4 :     if ((get_default_event_type() == EVENT_SYNC_CACHE) &&
     535            2 :         (get_handler_type() != CTRL_NOHANDLER)) {
     536            0 :         pr_error("Sync caches not available in daemon mode\n");
     537            0 :         return -1;
     538              :     }
     539              : 
     540              :     /* Retrieve ECUID from dlt.conf */
     541            2 :     if (get_ecuid() == NULL)
     542            0 :         set_ecuid(NULL);
     543              : 
     544              :     return 0;
     545              : }
     546              : 
     547              : #if !defined(DLT_SYSTEMD_ENABLE)
     548            0 : int sd_notify(int unset_environment, const char *state)
     549              : {
     550              :     /* Satisfy Compiler for warnings */
     551              :     (void)unset_environment;
     552              :     (void)state;
     553            0 :     return 0;
     554              : }
     555              : #endif
     556              : 
     557              : /** @brief Entry point
     558              :  *
     559              :  * Execute the argument parser and call the main feature accordingly.
     560              :  *
     561              :  * @param argc The amount of arguments
     562              :  * @param argv The table of arguments
     563              :  *
     564              :  * @return 0 on success, -1 otherwise
     565              :  */
     566            2 : int main(int argc, char *argv[])
     567              : {
     568              :     int ret = 0;
     569              : 
     570            2 :     set_timeout(DLT_CTRL_TIMEOUT);
     571            2 :     set_send_serial_header(0);
     572            2 :     set_resync_serial_header(0);
     573              : 
     574              :     /* Get command line arguments */
     575            2 :     if (parse_args(argc, argv) != 0)
     576              :         return -1;
     577              : 
     578              :     /* all parameter valid, start communication with daemon or setup
     579              :      * communication with control daemon */
     580            2 :     if (get_handler_type() == CTRL_NOHANDLER) {
     581            2 :         pr_verbose("One shot.\n");
     582              : 
     583            2 :         ret = dlt_logstorage_ctrl_single_request();
     584              : 
     585            2 :         if (ret < 0)
     586            0 :             pr_error("Message failed to be send. Please check DLT config.\n");
     587              :     }
     588              :     else {
     589            0 :         pr_verbose("Entering in daemon mode.\n");
     590              : 
     591              :         /* Let's daemonize */
     592              :         if (sd_notify(0, "READY=1") <= 0) {
     593            0 :             pr_verbose("SD notify failed, manually daemonizing.\n");
     594              : 
     595              :             /* No message can be sent or Systemd is not available.
     596              :              * Daemonizing manually.
     597              :              */
     598            0 :             if (daemon(1, 1)) {
     599            0 :                 pr_error("Failed to daemonize: %s\n", strerror(errno));
     600            0 :                 return EXIT_FAILURE;
     601              :             }
     602              :         }
     603              : 
     604            0 :         pr_verbose("Executing the event loop\n");
     605            0 :         ret = dlt_logstorage_ctrl_setup_event_loop();
     606              :     }
     607              : 
     608            2 :     pr_verbose("Exiting.\n");
     609              :     return ret;
     610              : }
        

Generated by: LCOV version 2.0-1