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: 45.8 % 24 11
Test Date: 2026-08-27 10:11:10 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              : #ifdef 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              :     } else {
      60              :         const char* sock_name = basename(sock_path);
      61              :         if (sock_name == NULL) {
      62              :             dlt_log(LOG_WARNING, "dlt_daemon_unix_android_get_socket: can't get socket name from its path");
      63              :             ret = DLT_RETURN_ERROR;
      64              :         } else {
      65              :             *sock = android_get_control_socket(sock_name);
      66              :             if (*sock < 0) {
      67              :                 dlt_log(LOG_WARNING, "dlt_daemon_unix_android_get_socket: can get socket from init");
      68              :                 ret = DLT_RETURN_ERROR;
      69              :             } else {
      70              :                 if (listen(*sock, 1) == -1) {
      71              :                     dlt_vlog(LOG_WARNING, "unix socket: listen error: %s", strerror(errno));
      72              :                     ret = DLT_RETURN_ERROR;
      73              :                 }
      74              :             }
      75              :         }
      76              :     }
      77              : 
      78              :     return ret;
      79              : }
      80              : #endif
      81              : 
      82            1 : int dlt_daemon_unix_socket_open(int* sock, char* sock_path, int type, int mask)
      83              : {
      84              :     struct sockaddr_un addr;
      85              :     mode_t old_mask;
      86              : 
      87            1 :     if ((sock == NULL) || (sock_path == NULL)) {
      88            0 :         dlt_log(LOG_ERR, "dlt_daemon_unix_socket_open: arguments invalid");
      89            0 :         return -1;
      90              :     }
      91              : 
      92              : #ifdef DLT_SYSTEM_SOCKET_ACTIVATION_ENABLE
      93              : 
      94              :     char** names = NULL;
      95              :     const int num_fds = sd_listen_fds_with_names(0, &names);
      96              :     bool sd_socket_open = false;
      97              :     int i;
      98              : 
      99              :     if (num_fds <= 0) {
     100              :         dlt_vlog(LOG_WARNING, "unix socket: no sockets configured via systemd, error: %s\n", strerror(errno));
     101              :     } else {
     102              :         for (i = 0; i < num_fds; ++i) {
     103              :             if (strcmp(sock_path, names[i]) != 0) {
     104              :                 continue;
     105              :             }
     106              : 
     107              :             if (sd_is_socket_unix(i + SD_LISTEN_FDS_START, type, 1, names[i], strlen(names[i])) < 0) {
     108              :                 dlt_vlog(
     109              :                     LOG_WARNING,
     110              :                     "unix socket: socket with matching name is not of correct type or not in listen mode, error: %s\n",
     111              :                     strerror(errno));
     112              :                 continue;
     113              :             }
     114              : 
     115              :             *sock = i + SD_LISTEN_FDS_START;
     116              :             sd_socket_open = true;
     117              :             dlt_vlog(LOG_INFO, "unix socket: sock_path %s found systemd socket %s\n", sock_path, names[i]);
     118              :             break;
     119              :         }
     120              : 
     121              :         /*
     122              :          * The caller [of sd_listen_fds_with_names] needs to free the array
     123              :          * itself and each of its elements with libc's free() call after use.
     124              :          * */
     125              :         for (i = 0; i < num_fds; ++i) {
     126              :             free(names[i]);
     127              :         }
     128              :         free(names);
     129              :     }
     130              : 
     131              :     if (!sd_socket_open) {
     132              :         dlt_vlog(LOG_INFO, "unix socket: sock_path %s no systemd socket found\n", sock_path);
     133              : #endif
     134              : 
     135            1 :         if ((*sock = socket(AF_UNIX, type, 0)) == -1) {
     136            0 :             dlt_log(LOG_WARNING, "unix socket: socket() error");
     137            0 :             return -1;
     138              :         }
     139              : 
     140              :         memset(&addr, 0, sizeof(addr));
     141            1 :         addr.sun_family = AF_UNIX;
     142              :         memcpy(addr.sun_path, sock_path, sizeof(addr.sun_path));
     143              : 
     144            1 :         if (unlink(sock_path) != 0) {
     145            1 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n", __func__, strerror(errno));
     146              :         }
     147              : 
     148              :         /* set appropriate access permissions */
     149            1 :         old_mask = umask((mode_t)mask);
     150              : 
     151            1 :         if (bind(*sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
     152            0 :             dlt_vlog(LOG_WARNING, "%s: bind() error (%s)\n", __func__, strerror(errno));
     153            0 :             return -1;
     154              :         }
     155              : 
     156            1 :         if (listen(*sock, 1) == -1) {
     157            0 :             dlt_vlog(LOG_WARNING, "%s: listen error (%s)\n", __func__, strerror(errno));
     158            0 :             return -1;
     159              :         }
     160              : 
     161              :         /* restore permissions */
     162            1 :         umask((mode_t)old_mask);
     163              : 
     164              : #ifdef DLT_SYSTEM_SOCKET_ACTIVATION_ENABLE
     165              :     }  // end of: if (!sd_socket_open) {
     166              : #endif
     167              : 
     168              : 
     169            1 :     return 0;
     170              : }
     171              : 
     172            0 : int dlt_daemon_unix_socket_close(int sock)
     173              : {
     174            0 :     int ret = close(sock);
     175              : 
     176            0 :     if (ret != 0) {
     177            0 :         dlt_vlog(LOG_WARNING, "unix socket close failed: %s", strerror(errno));
     178              :     }
     179              : 
     180            0 :     return ret;
     181              : }
        

Generated by: LCOV version 2.0-1