LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_unix_socket.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 44.4 % 27 12
Test Date: 2025-03-25 20:53:42 Functions: 50.0 % 2 1

            Line data    Source code
       1              : /*
       2              :  * SPDX license identifier: MPL-2.0
       3              :  *
       4              :  * Copyright (C) 2015, Advanced Driver Information Technology
       5              :  * Copyright of Advanced Driver Information Technology, Bosch and Denso
       6              :  *
       7              :  * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
       8              :  *
       9              :  * This Source Code Form is subject to the terms of the
      10              :  * Mozilla Public License (MPL), v. 2.0.
      11              :  * If a copy of the MPL was not distributed with this file,
      12              :  * You can obtain one at http://mozilla.org/MPL/2.0/.
      13              :  *
      14              :  * For further information see http://www.covesa.org/.
      15              :  */
      16              : 
      17              : /*!
      18              :  * \author
      19              :  * Christoph Lipka <clipka@jp.adit-jv.com>
      20              :  *
      21              :  * \copyright Copyright © 2015 ADIT. \n
      22              :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      23              :  *
      24              :  * \file dlt_daemon_unix_socket.c
      25              :  */
      26              : 
      27              : #include <stdio.h>
      28              : #include <stdlib.h>
      29              : #include <string.h>
      30              : #include <sys/un.h>
      31              : #if defined(ANDROID)
      32              : #   include <cutils/sockets.h> /* for android_get_control_socket() */
      33              : #   include <libgen.h> /* for basename() */
      34              : #else
      35              : #   include <sys/socket.h> /* for socket(), connect(), (), and recv() */
      36              : #endif
      37              : #include <sys/types.h>
      38              : #include <sys/stat.h>
      39              : #include <syslog.h>
      40              : #include <errno.h>
      41              : #if DLT_SYSTEM_SOCKET_ACTIVATION_ENABLE
      42              : #include <systemd/sd-daemon.h>
      43              : #endif
      44              : 
      45              : #include "dlt-daemon.h"
      46              : #include "dlt_common.h"
      47              : #include "dlt-daemon_cfg.h"
      48              : #include "dlt_daemon_socket.h"
      49              : #include "dlt_daemon_unix_socket.h"
      50              : 
      51              : #ifdef ANDROID
      52              : DltReturnValue dlt_daemon_unix_android_get_socket(int *sock, const char *sock_path)
      53              : {
      54              :     DltReturnValue ret = DLT_RETURN_OK;
      55              : 
      56              :     if ((sock == NULL) || (sock_path == NULL)) {
      57              :         dlt_log(LOG_ERR, "dlt_daemon_unix_android_get_socket: arguments invalid");
      58              :         ret = DLT_RETURN_WRONG_PARAMETER;
      59              :     }
      60              :     else {
      61              :         const char* sock_name = basename(sock_path);
      62              :         if (sock_name == NULL) {
      63              :             dlt_log(LOG_WARNING,
      64              :                     "dlt_daemon_unix_android_get_socket: can't get socket name from its path");
      65              :             ret = DLT_RETURN_ERROR;
      66              :         }
      67              :         else {
      68              :             *sock = android_get_control_socket(sock_name);
      69              :             if (*sock < 0) {
      70              :                 dlt_log(LOG_WARNING,
      71              :                         "dlt_daemon_unix_android_get_socket: can get socket from init");
      72              :                 ret = DLT_RETURN_ERROR;
      73              :             }
      74              :             else {
      75              :                 if (listen(*sock, 1) == -1) {
      76              :                     dlt_vlog(LOG_WARNING, "unix socket: listen error: %s", strerror(errno));
      77              :                     ret = DLT_RETURN_ERROR;
      78              :                 }
      79              :             }
      80              :         }
      81              :     }
      82              : 
      83              :     return ret;
      84              : }
      85              : #endif
      86              : 
      87            9 : int dlt_daemon_unix_socket_open(int *sock, char *sock_path, int type, int mask)
      88              : {
      89              :     struct sockaddr_un addr;
      90              :     int old_mask;
      91              : 
      92            9 :     if ((sock == NULL) || (sock_path == NULL)) {
      93            0 :         dlt_log(LOG_ERR, "dlt_daemon_unix_socket_open: arguments invalid");
      94            0 :         return -1;
      95              :     }
      96              : 
      97              : #ifdef DLT_SYSTEM_SOCKET_ACTIVATION_ENABLE
      98              : 
      99              :     char **names = NULL;
     100              :     const int num_fds = sd_listen_fds_with_names(0, &names);
     101              :     bool sd_socket_open = false;
     102              :     int i;
     103              : 
     104              :     if (num_fds <= 0) {
     105              :         dlt_vlog(LOG_WARNING, "unix socket: no sockets configured via systemd, error: %s\n", strerror(errno));
     106              :     } else {
     107              :         for (i = 0; i < num_fds; ++i) {
     108              :             if (strcmp(sock_path, names[i]) != 0) {
     109              :                 continue;
     110              :             }
     111              : 
     112              :             if (sd_is_socket_unix(i + SD_LISTEN_FDS_START, type, 1, names[i], strlen(names[i])) < 0) {
     113              :                 dlt_vlog(LOG_WARNING,
     114              :                         "unix socket: socket with matching name is not of correct type or not in listen mode, error: %s\n",
     115              :                         strerror(errno));
     116              :                 continue;
     117              :             }
     118              : 
     119              :             *sock = i + SD_LISTEN_FDS_START;
     120              :             sd_socket_open = true;
     121              :             dlt_vlog(LOG_INFO, "unix socket: sock_path %s found systemd socket %s\n", sock_path, names[i]);
     122              :             break;
     123              :         }
     124              : 
     125              :         /*
     126              :          * The caller [of sd_listen_fds_with_names] needs to free the array
     127              :          * itself and each of its elements with libc's free() call after use.
     128              :          * */
     129              :         for (i = 0; i < num_fds; ++i) {
     130              :             free(names[i]);
     131              :         }
     132              :         free(names);
     133              :     }
     134              : 
     135              :     if (!sd_socket_open) {
     136              :         dlt_vlog(LOG_INFO, "unix socket: sock_path %s no systemd socket found\n", sock_path);
     137              : #endif
     138              : 
     139            9 :     if ((*sock = socket(AF_UNIX, type, 0)) == -1) {
     140            0 :         dlt_log(LOG_WARNING, "unix socket: socket() error");
     141            0 :         return -1;
     142              :     }
     143              : 
     144              :     memset(&addr, 0, sizeof(addr));
     145            9 :     addr.sun_family = AF_UNIX;
     146              :     memcpy(addr.sun_path, sock_path, sizeof(addr.sun_path));
     147              : 
     148            9 :     if (unlink(sock_path) != 0) {
     149            8 :         dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
     150            8 :                 __func__, strerror(errno));
     151              :     }
     152              : 
     153              :     /* set appropriate access permissions */
     154            9 :     old_mask = umask(mask);
     155              : 
     156            9 :     if (bind(*sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
     157            0 :         dlt_vlog(LOG_WARNING, "%s: bind() error (%s)\n", __func__,
     158            0 :                  strerror(errno));
     159            0 :         return -1;
     160              :     }
     161              : 
     162            9 :     if (listen(*sock, 1) == -1) {
     163            0 :         dlt_vlog(LOG_WARNING, "%s: listen error (%s)\n", __func__,
     164            0 :                  strerror(errno));
     165            0 :         return -1;
     166              :     }
     167              : 
     168              :     /* restore permissions */
     169            9 :     umask(old_mask);
     170              : 
     171              : #ifdef DLT_SYSTEM_SOCKET_ACTIVATION_ENABLE
     172              :     } // end of: if (!sd_socket_open) {
     173              : #endif
     174              : 
     175              : 
     176            9 :     return 0;
     177              : }
     178              : 
     179            0 : int dlt_daemon_unix_socket_close(int sock)
     180              : {
     181            0 :     int ret = close(sock);
     182              : 
     183            0 :     if (ret != 0) {
     184            0 :         dlt_vlog(LOG_WARNING, "unix socket close failed: %s", strerror(errno));
     185              :     }
     186              : 
     187            0 :     return ret;
     188              : }
        

Generated by: LCOV version 2.0-1