LCOV - code coverage report
Current view: top level - rc-local-generator - rc-local-generator.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 28 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 4 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 68 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <stdio.h>
       5                 :            : #include <unistd.h>
       6                 :            : 
       7                 :            : #include "generator.h"
       8                 :            : #include "log.h"
       9                 :            : #include "mkdir.h"
      10                 :            : #include "string-util.h"
      11                 :            : #include "util.h"
      12                 :            : 
      13                 :            : static const char *arg_dest = NULL;
      14                 :            : 
      15                 :            : /* So you are reading this, and might wonder: why is this implemented as a generator rather than as a plain, statically
      16                 :            :  * enabled service that carries appropriate ConditionFileIsExecutable= lines? The answer is this: conditions bypass
      17                 :            :  * execution of a service's binary, but they have no influence on unit dependencies. Thus, a service that is
      18                 :            :  * conditioned out will still act as synchronization point in the dependency tree, and we'd rather not have that for
      19                 :            :  * these two legacy scripts. */
      20                 :            : 
      21                 :          0 : static int add_symlink(const char *service, const char *where) {
      22                 :            :         const char *from, *to;
      23                 :            : 
      24         [ #  # ]:          0 :         assert(service);
      25         [ #  # ]:          0 :         assert(where);
      26                 :            : 
      27   [ #  #  #  #  :          0 :         from = strjoina(SYSTEM_DATA_UNIT_PATH "/", service);
          #  #  #  #  #  
                #  #  # ]
      28   [ #  #  #  #  :          0 :         to = strjoina(arg_dest, "/", where, ".wants/", service);
          #  #  #  #  #  
                #  #  # ]
      29                 :            : 
      30                 :          0 :         (void) mkdir_parents_label(to, 0755);
      31                 :            : 
      32         [ #  # ]:          0 :         if (symlink(from, to) < 0) {
      33         [ #  # ]:          0 :                 if (errno == EEXIST)
      34                 :          0 :                         return 0;
      35                 :            : 
      36         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to create symlink %s: %m", to);
      37                 :            :         }
      38                 :            : 
      39                 :          0 :         return 1;
      40                 :            : }
      41                 :            : 
      42                 :          0 : static int check_executable(const char *path) {
      43         [ #  # ]:          0 :         assert(path);
      44                 :            : 
      45         [ #  # ]:          0 :         if (access(path, X_OK) < 0) {
      46         [ #  # ]:          0 :                 if (errno == ENOENT)
      47         [ #  # ]:          0 :                         return log_debug_errno(errno, "%s does not exist, skipping.", path);
      48         [ #  # ]:          0 :                 if (errno == EACCES)
      49         [ #  # ]:          0 :                         return log_info_errno(errno, "%s is not marked executable, skipping.", path);
      50                 :            : 
      51         [ #  # ]:          0 :                 return log_warning_errno(errno, "Couldn't determine if %s exists and is executable, skipping: %m", path);
      52                 :            :         }
      53                 :            : 
      54                 :          0 :         return 0;
      55                 :            : }
      56                 :            : 
      57                 :          0 : static int run(const char *dest, const char *dest_early, const char *dest_late) {
      58                 :          0 :         int r = 0, k = 0;
      59                 :            : 
      60         [ #  # ]:          0 :         assert_se(arg_dest = dest);
      61                 :            : 
      62         [ #  # ]:          0 :         if (check_executable(RC_LOCAL_SCRIPT_PATH_START) >= 0) {
      63         [ #  # ]:          0 :                 log_debug("Automatically adding rc-local.service.");
      64                 :            : 
      65                 :          0 :                 r = add_symlink("rc-local.service", "multi-user.target");
      66                 :            :         }
      67                 :            : 
      68         [ #  # ]:          0 :         return r < 0 ? r : k;
      69                 :            : }
      70                 :            : 
      71   [ #  #  #  #  :          0 : DEFINE_MAIN_GENERATOR_FUNCTION(run);
          #  #  #  #  #  
                #  #  # ]

Generated by: LCOV version 1.14