LCOV - code coverage report
Current view: top level - libpkg - system_shlibs.c (source / functions) Hit Total Coverage
Test: plop Lines: 39 43 90.7 %
Date: 2024-12-30 07:09:03 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 35 42 83.3 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 1998 John D. Polstra
       3                 :            :  * Copyright (c) 2012 Matthew Seaman <matthew@FreeBSD.org>
       4                 :            :  * Copyright (c) 2024 The FreeBSD Foundation
       5                 :            :  *
       6                 :            :  * This software was developed in part by Isaac Freund <ifreund@freebsdfoundation.org>
       7                 :            :  * under sponsorship from the FreeBSD Foundation.
       8                 :            :  *
       9                 :            :  * SPDX-License-Identifier: BSD-2-Clause
      10                 :            :  */
      11                 :            : 
      12                 :            : #include <assert.h>
      13                 :            : #include <ctype.h>
      14                 :            : #include <dirent.h>
      15                 :            : #include <errno.h>
      16                 :            : #include <string.h>
      17                 :            : 
      18                 :            : #include "pkg.h"
      19                 :            : #include "pkghash.h"
      20                 :            : #include "private/event.h"
      21                 :            : #include "private/pkg.h"
      22                 :            : #include "xmalloc.h"
      23                 :            : 
      24                 :            : static int
      25                 :        495 : scan_dir_for_shlibs(pkghash **shlib_list, const char *dir,
      26                 :            :     enum pkg_shlib_flags flags)
      27                 :            : {
      28                 :        495 :         DIR *dirp= opendir(dir);
      29         [ +  + ]:        495 :         if (dirp == NULL) {
      30         [ +  - ]:        228 :                 if (errno == ENOENT) {
      31                 :        228 :                         return (EPKG_OK);
      32                 :            :                 }
      33                 :          0 :                 pkg_errno("Failed to open '%s' to scan for shared libraries", dir);
      34                 :          0 :                 return (EPKG_FATAL);
      35                 :            :         }
      36                 :            : 
      37                 :            :         struct dirent *dp;
      38         [ +  + ]:      47793 :         while ((dp = readdir(dirp)) != NULL) {
      39                 :            :                 /* Only regular files and sym-links. On some
      40                 :            :                    filesystems d_type is not set, on these the d_type
      41                 :            :                    field will be DT_UNKNOWN. */
      42   [ +  +  +  +  :      47526 :                 if (dp->d_type != DT_REG && dp->d_type != DT_LNK &&
                   -  + ]
      43                 :       1602 :                     dp->d_type != DT_UNKNOWN)
      44                 :       1602 :                         continue;
      45                 :            : 
      46                 :      45924 :                 int len = strlen(dp->d_name);
      47                 :            :                 /* Name can't be shorter than "libx.so" */
      48   [ +  +  +  + ]:      45924 :                 if (len < 7 || strncmp(dp->d_name, "lib", 3) != 0)
      49                 :       5785 :                         continue;
      50                 :            : 
      51                 :      40139 :                 const char *vers = dp->d_name + len;
      52   [ -  +  +  + ]:     111072 :                 while (vers > dp->d_name &&
      53   [ +  +  +  + ]:      70933 :                        (isdigit(*(vers-1)) || *(vers-1) == '.'))
      54                 :      30794 :                         vers--;
      55         [ +  + ]:      40139 :                 if (vers == dp->d_name + len) {
      56         [ +  + ]:      25632 :                         if (strncmp(vers - 3, ".so", 3) != 0)
      57                 :      12549 :                                 continue;
      58   [ +  -  -  + ]:      27590 :                 } else if (vers < dp->d_name + 3 ||
      59                 :      14507 :                     strncmp(vers - 3, ".so.", 4) != 0)
      60                 :          0 :                         continue;
      61                 :            : 
      62                 :            :                 /* We have a valid shared library name. */
      63                 :      27590 :                 char *full = pkg_shlib_name_with_flags(dp->d_name, flags);
      64   [ +  +  -  + ]:      55091 :                 pkghash_safe_add(*shlib_list, full, NULL, NULL);
      65                 :      27590 :                 free(full);
      66                 :            :         }
      67                 :            : 
      68                 :        267 :         closedir(dirp);
      69                 :            : 
      70                 :        267 :         return (EPKG_OK);
      71                 :        495 : }
      72                 :            : 
      73                 :            : static struct {
      74                 :            :         const char *dir;
      75                 :            :         enum pkg_shlib_flags flags;
      76                 :            : } system_shlib_table[] = {
      77                 :            :         {"/lib", PKG_SHLIB_FLAGS_NONE },
      78                 :            :         {"/usr/lib", PKG_SHLIB_FLAGS_NONE },
      79                 :            :         {"/usr/lib32", PKG_SHLIB_FLAGS_COMPAT_32 },
      80                 :            : };
      81                 :            : 
      82                 :            : int
      83                 :        165 : scan_system_shlibs(pkghash **system_shlibs, const char *rootdir)
      84                 :            : {
      85         [ +  + ]:        660 :         for (int i = 0; i < NELEM(system_shlib_table); i++) {
      86                 :            :                 char *dir;
      87         [ +  + ]:        495 :                 if (rootdir != NULL) {
      88                 :        228 :                         xasprintf(&dir, "%s%s", rootdir, system_shlib_table[i].dir);
      89                 :        228 :                 } else {
      90                 :        267 :                         dir = xstrdup(system_shlib_table[i].dir);
      91                 :            :                 }
      92                 :        495 :                 int ret = scan_dir_for_shlibs(system_shlibs, dir, system_shlib_table[i].flags);
      93                 :        495 :                 free(dir);
      94         [ -  + ]:        495 :                 if (ret != EPKG_OK) {
      95                 :          0 :                         return (ret);
      96                 :            :                 }
      97                 :        495 :         }
      98                 :            : 
      99                 :        165 :         return (EPKG_OK);
     100                 :        165 : }

Generated by: LCOV version 1.15