LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_unix_socket.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 12 27 44.4 %
Date: 2024-10-22 04:07:23 Functions: 1 2 50.0 %

          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 1.14