1 /* Copyright (C) 1999-2023 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published
6 by the Free Software Foundation; version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <https://www.gnu.org/licenses/>. */
17 #define PROCINFO_CLASS static
30 #include <stdio_ext.h>
35 #include <sys/fcntl.h>
38 #include <sys/types.h>
44 #include <dl-hwcaps.h>
45 #include <dl-is_dso.h>
47 #include <dl-procinfo.h>
50 # define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
53 /* Get libc version number. */
56 #define PACKAGE _libc_intl_domainname
58 /* List of directories to handle. */
65 const char *from_file
;
68 /* Non-NULL for subdirectories under a glibc-hwcaps subdirectory. */
69 struct glibc_hwcaps_subdirectory
*hwcaps
;
71 struct dir_entry
*next
;
74 /* The list is unsorted, contains no duplicates. Entries are added at
76 static struct dir_entry
*dir_entries
;
78 /* Flags for different options. */
80 static int opt_print_cache
;
85 /* Format to support. */
86 enum opt_format opt_format
= opt_format_new
;
89 static int opt_build_cache
= 1;
91 /* Enable symbolic link processing. If set, create or update symbolic
92 links, and remove stale symbolic links. */
93 static int opt_link
= 1;
95 /* Only process directories specified on the command line. */
96 static int opt_only_cline
;
98 /* Path to root for chroot. */
99 static char *opt_chroot
;
101 /* Manually link given shared libraries. */
102 static int opt_manual_link
;
104 /* Should we ignore an old auxiliary cache file? */
105 static int opt_ignore_aux_cache
;
107 /* Cache file to use. */
108 static char *cache_file
;
110 /* Configuration file. */
111 static const char *config_file
;
113 /* Name and version of program. */
114 static void print_version (FILE *stream
, struct argp_state
*state
);
115 void (*argp_program_version_hook
) (FILE *, struct argp_state
*)
118 /* Function to print some extra text in the help message. */
119 static char *more_help (int key
, const char *text
, void *input
);
121 /* Definitions of arguments for argp functions. */
122 static const struct argp_option options
[] =
124 { "print-cache", 'p', NULL
, 0, N_("Print cache"), 0},
125 { "verbose", 'v', NULL
, 0, N_("Generate verbose messages"), 0},
126 { NULL
, 'N', NULL
, 0, N_("Don't build cache"), 0},
127 { NULL
, 'X', NULL
, 0, N_("Don't update symbolic links"), 0},
128 { NULL
, 'r', N_("ROOT"), 0, N_("Change to and use ROOT as root directory"), 0},
129 { NULL
, 'C', N_("CACHE"), 0, N_("Use CACHE as cache file"), 0},
130 { NULL
, 'f', N_("CONF"), 0, N_("Use CONF as configuration file"), 0},
131 { NULL
, 'n', NULL
, 0, N_("Only process directories specified on the command line. Don't build cache."), 0},
132 { NULL
, 'l', NULL
, 0, N_("Manually link individual libraries."), 0},
133 { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new (default), old, or compat"), 0},
134 { "ignore-aux-cache", 'i', NULL
, 0, N_("Ignore auxiliary cache file"), 0},
135 { NULL
, 0, NULL
, 0, NULL
, 0 }
138 #define PROCINFO_CLASS static
139 #include <dl-procinfo.c>
141 /* Short description of program. */
142 static const char doc
[] = N_("Configure Dynamic Linker Run Time Bindings.");
144 /* Prototype for option handler. */
145 static error_t
parse_opt (int key
, char *arg
, struct argp_state
*state
);
147 /* Data structure to communicate with argp functions. */
148 static struct argp argp
=
150 options
, parse_opt
, NULL
, doc
, NULL
, more_help
, NULL
153 /* Handle program arguments. */
155 parse_opt (int key
, char *arg
, struct argp_state
*state
)
161 /* Ignore auxiliary cache since we use non-standard cache. */
162 opt_ignore_aux_cache
= 1;
168 opt_ignore_aux_cache
= 1;
193 if (strcmp (arg
, "old") == 0)
194 opt_format
= opt_format_old
;
195 else if (strcmp (arg
, "compat") == 0)
196 opt_format
= opt_format_compat
;
197 else if (strcmp (arg
, "new") == 0)
198 opt_format
= opt_format_new
;
201 return ARGP_ERR_UNKNOWN
;
207 /* Print bug-reporting information in the help message. */
209 more_help (int key
, const char *text
, void *input
)
214 case ARGP_KEY_HELP_EXTRA
:
215 /* We print some extra information. */
216 if (asprintf (&tp
, gettext ("\
217 For bug reporting instructions, please see:\n\
218 %s.\n"), REPORT_BUGS_TO
) < 0)
224 return (char *) text
;
227 /* Print the version information. */
229 print_version (FILE *stream
, struct argp_state
*state
)
231 fprintf (stream
, "ldconfig %s%s\n", PKGVERSION
, VERSION
);
232 fprintf (stream
, gettext ("\
233 Copyright (C) %s Free Software Foundation, Inc.\n\
234 This is free software; see the source for copying conditions. There is NO\n\
235 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
237 fprintf (stream
, gettext ("Written by %s.\n"),
241 /* Allocate a new subdirectory with full path PATH under ENTRY, using
242 inode data from *ST. */
243 static struct dir_entry
*
244 new_sub_entry (const struct dir_entry
*entry
, const char *path
,
245 const struct stat
*st
)
247 struct dir_entry
*new_entry
= xmalloc (sizeof (struct dir_entry
));
248 new_entry
->from_file
= entry
->from_file
;
249 new_entry
->from_line
= entry
->from_line
;
250 new_entry
->path
= xstrdup (path
);
251 new_entry
->flag
= entry
->flag
;
252 new_entry
->hwcaps
= NULL
;
253 new_entry
->next
= NULL
;
254 new_entry
->ino
= st
->st_ino
;
255 new_entry
->dev
= st
->st_dev
;
259 /* Add a single directory entry. Return true if the directory is
260 actually added (because it is not a duplicate). */
262 add_single_dir (struct dir_entry
*entry
, int verbose
)
264 struct dir_entry
*ptr
, *prev
;
271 /* Check for duplicates. */
272 if (ptr
->ino
== entry
->ino
&& ptr
->dev
== entry
->dev
)
274 if (opt_verbose
&& verbose
)
276 error (0, 0, _("Path `%s' given more than once"), entry
->path
);
277 fprintf (stderr
, _("(from %s:%d and %s:%d)\n"),
278 entry
->from_file
, entry
->from_line
,
279 ptr
->from_file
, ptr
->from_line
);
281 /* Use the newer information. */
282 ptr
->flag
= entry
->flag
;
291 /* Is this the first entry? */
292 if (ptr
== NULL
&& dir_entries
== NULL
)
294 else if (ptr
== NULL
)
299 /* Check if PATH contains a "glibc-hwcaps" subdirectory. If so, queue
300 its subdirectories for glibc-hwcaps processing. */
302 add_glibc_hwcaps_subdirectories (struct dir_entry
*entry
, const char *path
)
304 /* glibc-hwcaps subdirectories do not nest. */
305 assert (entry
->hwcaps
== NULL
);
308 if (asprintf (&glibc_hwcaps
, "%s/" GLIBC_HWCAPS_SUBDIRECTORY
, path
) < 0)
309 error (EXIT_FAILURE
, errno
, _("Could not form glibc-hwcaps path"));
311 DIR *dir
= opendir (glibc_hwcaps
);
317 struct dirent64
*e
= readdir64 (dir
);
323 error (EXIT_FAILURE
, errno
, _("Listing directory %s"), path
);
326 /* Ignore hidden subdirectories, including "." and "..", and
327 regular files. File names containing a ':' cannot be
328 looked up by the dynamic loader, so skip those as
330 if (e
->d_name
[0] == '.' || e
->d_type
== DT_REG
331 || strchr (e
->d_name
, ':') != NULL
)
334 /* See if this entry eventually resolves to a directory. */
336 if (fstatat (dirfd (dir
), e
->d_name
, &st
, 0) < 0)
337 /* Ignore unreadable entries. */
340 if (S_ISDIR (st
.st_mode
))
342 /* This is a directory, so it needs to be scanned for
343 libraries, associated with the hwcaps implied by the
344 subdirectory name. */
346 if (asprintf (&new_path
, "%s/" GLIBC_HWCAPS_SUBDIRECTORY
"/%s",
347 /* Use non-canonicalized path here. */
348 entry
->path
, e
->d_name
) < 0)
349 error (EXIT_FAILURE
, errno
,
350 _("Could not form glibc-hwcaps path"));
351 struct dir_entry
*new_entry
= new_sub_entry (entry
, new_path
,
354 new_entry
->hwcaps
= new_glibc_hwcaps_subdirectory (e
->d_name
);
355 add_single_dir (new_entry
, 0);
365 /* Add one directory to the list of directories to process. */
367 add_dir_1 (const char *line
, const char *from_file
, int from_line
)
370 struct dir_entry
*entry
= xmalloc (sizeof (struct dir_entry
));
371 entry
->hwcaps
= NULL
;
374 entry
->from_file
= strdup (from_file
);
375 entry
->from_line
= from_line
;
377 entry
->path
= xstrdup (line
);
378 entry
->flag
= FLAG_ELF_LIBC6
;
380 /* Canonify path: for now only remove leading and trailing
381 whitespace and the trailing slashes. */
382 i
= strlen (entry
->path
);
384 while (i
> 0 && isspace (entry
->path
[i
- 1]))
385 entry
->path
[--i
] = '\0';
387 while (i
> 0 && entry
->path
[i
- 1] == '/')
388 entry
->path
[--i
] = '\0';
397 char *path
= entry
->path
;
398 if (opt_chroot
!= NULL
)
399 path
= chroot_canon (opt_chroot
, path
);
401 struct stat stat_buf
;
402 if (path
== NULL
|| stat (path
, &stat_buf
))
405 error (0, errno
, _("Can't stat %s"), entry
->path
);
411 entry
->ino
= stat_buf
.st_ino
;
412 entry
->dev
= stat_buf
.st_dev
;
414 if (add_single_dir (entry
, 1))
415 /* Add glibc-hwcaps subdirectories if present. */
416 add_glibc_hwcaps_subdirectories (entry
, path
);
419 if (opt_chroot
!= NULL
)
424 add_dir (const char *line
)
426 add_dir_1 (line
, "<builtin>", 0);
430 chroot_stat (const char *real_path
, const char *path
, struct stat
*st
)
436 return stat (real_path
, st
);
438 ret
= lstat (real_path
, st
);
439 if (ret
|| !S_ISLNK (st
->st_mode
))
442 canon_path
= chroot_canon (opt_chroot
, path
);
443 if (canon_path
== NULL
)
446 ret
= stat (canon_path
, st
);
451 /* Create a symbolic link from soname to libname in directory path. */
453 create_links (const char *real_path
, const char *path
, const char *libname
,
456 char *full_libname
, *full_soname
;
457 char *real_full_libname
, *real_full_soname
;
458 struct stat stat_lib
, stat_so
, lstat_so
;
461 /* XXX: The logics in this function should be simplified. */
463 /* Get complete path. */
464 full_libname
= alloca (strlen (path
) + strlen (libname
) + 2);
465 full_soname
= alloca (strlen (path
) + strlen (soname
) + 2);
466 sprintf (full_libname
, "%s/%s", path
, libname
);
467 sprintf (full_soname
, "%s/%s", path
, soname
);
468 if (opt_chroot
!= NULL
)
470 real_full_libname
= alloca (strlen (real_path
) + strlen (libname
) + 2);
471 real_full_soname
= alloca (strlen (real_path
) + strlen (soname
) + 2);
472 sprintf (real_full_libname
, "%s/%s", real_path
, libname
);
473 sprintf (real_full_soname
, "%s/%s", real_path
, soname
);
477 real_full_libname
= full_libname
;
478 real_full_soname
= full_soname
;
481 /* Does soname already exist and point to the right library? */
482 if (chroot_stat (real_full_soname
, full_soname
, &stat_so
) == 0)
484 if (chroot_stat (real_full_libname
, full_libname
, &stat_lib
))
486 error (0, 0, _("Can't stat %s\n"), full_libname
);
489 if (stat_lib
.st_dev
== stat_so
.st_dev
490 && stat_lib
.st_ino
== stat_so
.st_ino
)
491 /* Link is already correct. */
493 else if (lstat (full_soname
, &lstat_so
) == 0
494 && !S_ISLNK (lstat_so
.st_mode
))
496 error (0, 0, _("%s is not a symbolic link\n"), full_soname
);
501 else if (lstat (real_full_soname
, &lstat_so
) != 0
502 || !S_ISLNK (lstat_so
.st_mode
))
503 /* Unless it is a stale symlink, there is no need to remove. */
507 printf ("\t%s -> %s", soname
, libname
);
509 if (do_link
&& opt_link
)
511 /* Remove old link. */
513 if (unlink (real_full_soname
))
515 error (0, 0, _("Can't unlink %s"), full_soname
);
518 /* Create symbolic link. */
519 if (do_link
&& symlink (libname
, real_full_soname
))
521 error (0, 0, _("Can't link %s to %s"), full_soname
, libname
);
527 fputs (_(" (changed)\n"), stdout
);
529 fputs (_(" (SKIPPED)\n"), stdout
);
532 else if (opt_verbose
)
533 fputs ("\n", stdout
);
536 /* Manually link the given library. */
538 manual_link (char *library
)
545 struct stat stat_buf
;
547 unsigned int isa_level
;
549 /* Prepare arguments for create_links call. Split library name in
550 directory and filename first. Since path is allocated, we've got
551 to be careful to free at the end. */
552 path
= xstrdup (library
);
553 libname
= strrchr (path
, '/');
557 /* Successfully split names. Check if path is just "/" to avoid
561 libname
= library
+ 1;
562 path
= xrealloc (path
, 2);
573 /* There's no path, construct one. */
575 path
= xrealloc (path
, 2);
579 if (opt_chroot
!= NULL
)
581 real_path
= chroot_canon (opt_chroot
, path
);
582 if (real_path
== NULL
)
584 error (0, errno
, _("Can't find %s"), path
);
588 real_library
= alloca (strlen (real_path
) + strlen (libname
) + 2);
589 sprintf (real_library
, "%s/%s", real_path
, libname
);
594 real_library
= library
;
597 /* Do some sanity checks first. */
598 if (lstat (real_library
, &stat_buf
))
600 error (0, errno
, _("Cannot lstat %s"), library
);
603 /* We don't want links here! */
604 else if (!S_ISREG (stat_buf
.st_mode
))
606 error (0, 0, _("Ignored file %s since it is not a regular file."),
611 if (process_file (real_library
, library
, libname
, &flag
, &isa_level
, &soname
,
614 error (0, 0, _("No link created since soname could not be found for %s"),
619 soname
= xstrdup (libname
);
620 create_links (real_path
, path
, libname
, soname
);
623 if (path
!= real_path
)
629 /* Read a whole directory and search for libraries.
630 The purpose is two-fold:
631 - search for libraries which will be added to the cache
632 - create symbolic links to the soname for each library
634 This has to be done separately for each directory.
636 To keep track of which libraries to add to the cache and which
637 links to create, we save a list of all libraries.
639 The algorithm is basically:
640 for all libraries in the directory do
641 get soname of library
642 if soname is already in list
643 if new library is newer, replace entry
644 otherwise ignore this library
645 otherwise add library to list
647 For example, if the two libraries libxy.so.1.1 and libxy.so.1.2
648 exist and both have the same soname, e.g. libxy.so, a symbolic link
649 is created from libxy.so.1.2 (the newer one) to libxy.so.
650 libxy.so.1.2 and libxy.so are added to the cache - but not
653 /* Information for one library. */
660 unsigned int isa_level
;
661 struct dlib_entry
*next
;
664 /* Skip some temporary DSO files. These files may be partially written
665 and lead to ldconfig crashes when examined. */
667 skip_dso_based_on_name (const char *name
, size_t len
)
669 /* Skip temporary files created by the prelink program. Files with
670 names like these are never really DSOs we want to look at. */
671 if (len
>= sizeof (".#prelink#") - 1)
673 if (strcmp (name
+ len
- sizeof (".#prelink#") + 1,
676 if (len
>= sizeof (".#prelink#.XXXXXX") - 1
677 && memcmp (name
+ len
- sizeof (".#prelink#.XXXXXX")
678 + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
681 /* Skip temporary files created by RPM. */
682 if (memchr (name
, len
, ';') != NULL
)
684 /* Skip temporary files created by dpkg. */
685 if (len
> 4 && memcmp (name
+ len
- 4, ".tmp", 4) == 0)
691 search_dir (const struct dir_entry
*entry
)
695 if (entry
->hwcaps
== NULL
)
696 printf ("%s:", entry
->path
);
698 printf ("%s: (hwcap: \"%s\")", entry
->path
,
699 glibc_hwcaps_subdirectory_name (entry
->hwcaps
));
700 printf (_(" (from %s:%d)\n"), entry
->from_file
, entry
->from_line
);
704 char *real_file_name
;
706 if (opt_chroot
!= NULL
)
707 dir_name
= chroot_canon (opt_chroot
, entry
->path
);
709 dir_name
= entry
->path
;
712 if (dir_name
== NULL
|| (dir
= opendir (dir_name
)) == NULL
)
715 error (0, errno
, _("Can't open directory %s"), entry
->path
);
716 if (opt_chroot
!= NULL
)
721 struct dirent64
*direntry
;
722 struct dlib_entry
*dlibs
= NULL
;
723 while ((direntry
= readdir64 (dir
)) != NULL
)
726 /* We only look at links and regular files. */
727 if (direntry
->d_type
!= DT_UNKNOWN
728 && direntry
->d_type
!= DT_LNK
729 && direntry
->d_type
!= DT_REG
730 && direntry
->d_type
!= DT_DIR
)
732 /* Does this file look like a shared library? The dynamic linker
733 is also considered as shared library. */
734 if (!_dl_is_dso (direntry
->d_name
)
735 && (direntry
->d_type
== DT_REG
|| entry
->hwcaps
== NULL
))
738 size_t len
= strlen (direntry
->d_name
);
739 if (skip_dso_based_on_name (direntry
->d_name
, len
))
741 if (asprintf (&file_name
, "%s/%s", entry
->path
, direntry
->d_name
) < 0)
742 error (EXIT_FAILURE
, errno
, _("Could not form library path"));
743 if (opt_chroot
!= NULL
)
745 if (asprintf (&real_file_name
, "%s/%s",
746 dir_name
, direntry
->d_name
) < 0)
747 error (EXIT_FAILURE
, errno
, _("Could not form library path"));
750 real_file_name
= xstrdup (file_name
);
752 struct stat lstat_buf
;
753 /* We optimize and try to do the lstat call only if needed. */
754 if (direntry
->d_type
!= DT_UNKNOWN
)
755 lstat_buf
.st_mode
= DTTOIF (direntry
->d_type
);
757 if (__glibc_unlikely (lstat (real_file_name
, &lstat_buf
)))
759 error (0, errno
, _("Cannot lstat %s"), file_name
);
763 struct stat stat_buf
;
764 int is_link
= S_ISLNK (lstat_buf
.st_mode
);
767 /* In case of symlink, we check if the symlink refers to
769 char *target_name
= real_file_name
;
770 if (opt_chroot
!= NULL
)
772 target_name
= chroot_canon (opt_chroot
, file_name
);
773 if (target_name
== NULL
)
775 if (strstr (file_name
, ".so") == NULL
)
776 error (0, 0, _("Input file %s not found.\n"), file_name
);
780 if (__glibc_unlikely (stat (target_name
, &stat_buf
)))
783 error (0, errno
, _("Cannot stat %s"), file_name
);
785 /* Remove stale symlinks. */
786 if (opt_link
&& strstr (direntry
->d_name
, ".so."))
787 unlink (real_file_name
);
789 if (opt_chroot
!= NULL
)
795 if (opt_chroot
!= NULL
)
798 /* lstat_buf is later stored, update contents. */
799 lstat_buf
.st_dev
= stat_buf
.st_dev
;
800 lstat_buf
.st_ino
= stat_buf
.st_ino
;
801 lstat_buf
.st_size
= stat_buf
.st_size
;
802 lstat_buf
.st_ctime
= stat_buf
.st_ctime
;
804 else if (!S_ISREG (lstat_buf
.st_mode
))
808 if (opt_chroot
!= NULL
&& is_link
)
810 real_name
= chroot_canon (opt_chroot
, file_name
);
811 if (real_name
== NULL
)
813 if (strstr (file_name
, ".so") == NULL
)
814 error (0, 0, _("Input file %s not found.\n"), file_name
);
819 real_name
= real_file_name
;
821 /* Call lstat if not done yet. */
823 && direntry
->d_type
!= DT_UNKNOWN
824 && __builtin_expect (lstat (real_file_name
, &lstat_buf
), 0))
826 error (0, errno
, _("Cannot lstat %s"), file_name
);
830 /* First search whether the auxiliary cache contains this
831 library already and it's not changed. */
833 unsigned int isa_level
;
834 if (!search_aux_cache (&lstat_buf
, &flag
, &isa_level
, &soname
))
836 if (process_file (real_name
, file_name
, direntry
->d_name
, &flag
,
837 &isa_level
, &soname
, is_link
, &lstat_buf
))
839 if (real_name
!= real_file_name
)
843 else if (opt_build_cache
)
844 add_to_aux_cache (&lstat_buf
, flag
, isa_level
, soname
);
848 soname
= xstrdup (direntry
->d_name
);
850 /* A link may just point to itself. */
853 /* If the path the link points to isn't its soname or it is not
854 the .so symlink for ld(1), we treat it as a normal file.
856 You should always do this:
858 libfoo.so -> SONAME -> Arbitrary package-chosen name.
860 e.g. libfoo.so -> libfoo.so.1 -> libfooimp.so.9.99.
861 Given a SONAME of libfoo.so.1.
863 You should *never* do this:
865 libfoo.so -> libfooimp.so.9.99
867 If you do, and your SONAME is libfoo.so.1, then libfoo.so
868 fails to point at the SONAME. In that case ldconfig may consider
869 libfoo.so as another implementation of SONAME and will create
870 symlinks against it causing problems when you try to upgrade
871 or downgrade. The problems will arise because ldconfig will,
872 depending on directory ordering, creat symlinks against libfoo.so
873 e.g. libfoo.so.1.2 -> libfoo.so, but when libfoo.so is removed
874 (typically by the removal of a development package not required
875 for the runtime) it will break the libfoo.so.1.2 symlink and the
876 application will fail to start. */
877 const char *real_base_name
= basename (real_file_name
);
879 if (strcmp (real_base_name
, soname
) != 0)
881 len
= strlen (real_base_name
);
882 if (len
< strlen (".so")
883 || strcmp (real_base_name
+ len
- strlen (".so"), ".so") != 0
884 || strncmp (real_base_name
, soname
, len
) != 0)
889 if (real_name
!= real_file_name
)
895 soname
= xstrdup (direntry
->d_name
);
898 /* Some sanity checks to print warnings. */
901 if (flag
== FLAG_ELF_LIBC6
&& entry
->flag
!= FLAG_ELF_LIBC6
)
902 error (0, 0, _("libc6 library %s in wrong directory"), file_name
);
905 /* Add library to list. */
906 struct dlib_entry
*dlib_ptr
;
907 for (dlib_ptr
= dlibs
; dlib_ptr
!= NULL
; dlib_ptr
= dlib_ptr
->next
)
909 /* Is soname already in list? */
910 if (strcmp (dlib_ptr
->soname
, soname
) == 0)
912 /* Prefer a file to a link, otherwise check which one
914 if ((!is_link
&& dlib_ptr
->is_link
)
915 || (is_link
== dlib_ptr
->is_link
916 && _dl_cache_libcmp (dlib_ptr
->name
, direntry
->d_name
) < 0))
918 /* It's newer - add it. */
919 /* Flag should be the same - sanity check. */
920 if (dlib_ptr
->flag
!= flag
)
921 error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
922 dlib_ptr
->name
, direntry
->d_name
, entry
->path
);
923 free (dlib_ptr
->name
);
924 dlib_ptr
->name
= xstrdup (direntry
->d_name
);
925 dlib_ptr
->is_link
= is_link
;
926 dlib_ptr
->isa_level
= isa_level
;
928 /* Don't add this library, abort loop. */
929 /* Also free soname, since it's dynamically allocated. */
934 /* Add the library if it's not already in. */
935 if (dlib_ptr
== NULL
)
937 dlib_ptr
= (struct dlib_entry
*)xmalloc (sizeof (struct dlib_entry
));
938 dlib_ptr
->name
= xstrdup (direntry
->d_name
);
939 dlib_ptr
->soname
= soname
;
940 dlib_ptr
->flag
= flag
;
941 dlib_ptr
->is_link
= is_link
;
942 dlib_ptr
->isa_level
= isa_level
;
943 /* Add at head of list. */
944 dlib_ptr
->next
= dlibs
;
950 free (real_file_name
);
955 /* Now dlibs contains a list of all libs - add those to the cache
956 and created all symbolic links. */
957 struct dlib_entry
*dlib_ptr
;
958 for (dlib_ptr
= dlibs
; dlib_ptr
!= NULL
; dlib_ptr
= dlib_ptr
->next
)
960 /* The cached file name is the soname for non-glibc-hwcaps
961 subdirectories (relying on symbolic links; this helps with
962 library updates that change the file name), and the actual
963 file for glibc-hwcaps subdirectories. */
964 const char *filename
;
965 if (entry
->hwcaps
== NULL
)
967 /* Don't create links to links. */
968 if (dlib_ptr
->is_link
== 0)
969 create_links (dir_name
, entry
->path
, dlib_ptr
->name
,
971 filename
= dlib_ptr
->soname
;
975 /* Do not create links in glibc-hwcaps subdirectories, but
976 still log the cache addition. */
978 printf ("\t%s -> %s\n", dlib_ptr
->soname
, dlib_ptr
->name
);
979 filename
= dlib_ptr
->name
;
982 add_to_cache (entry
->path
, filename
, dlib_ptr
->soname
,
983 dlib_ptr
->flag
, dlib_ptr
->isa_level
, entry
->hwcaps
);
986 /* Free all resources. */
990 free (dlib_ptr
->soname
);
991 free (dlib_ptr
->name
);
996 if (opt_chroot
!= NULL
&& dir_name
!= NULL
)
1000 /* Search through all libraries. */
1004 struct dir_entry
*entry
;
1006 for (entry
= dir_entries
; entry
!= NULL
; entry
= entry
->next
)
1009 /* Free all allocated memory. */
1012 entry
= dir_entries
;
1013 dir_entries
= dir_entries
->next
;
1020 static void parse_conf_include (const char *config_file
, unsigned int lineno
,
1021 bool do_chroot
, const char *pattern
);
1023 /* Parse configuration file. */
1025 parse_conf (const char *filename
, bool do_chroot
)
1031 unsigned int lineno
;
1033 if (do_chroot
&& opt_chroot
)
1035 canon
= chroot_canon (opt_chroot
, filename
);
1037 file
= fopen (canon
, "r");
1044 file
= fopen (filename
, "r");
1049 if (errno
!= ENOENT
)
1050 error (0, errno
, _("\
1051 Warning: ignoring configuration file that cannot be opened: %s"),
1053 if (canon
!= filename
)
1054 free ((char *) canon
);
1058 /* No threads use this stream. */
1059 __fsetlocking (file
, FSETLOCKING_BYCALLER
);
1061 if (canon
!= filename
)
1062 free ((char *) canon
);
1067 ssize_t n
= getline (&line
, &len
, file
);
1072 if (line
[n
- 1] == '\n')
1075 /* Because the file format does not know any form of quoting we
1076 can search forward for the next '#' character and if found
1077 make it terminating the line. */
1078 *strchrnul (line
, '#') = '\0';
1080 /* Remove leading whitespace. NUL is no whitespace character. */
1082 while (isspace (*cp
))
1085 /* If the line is blank it is ignored. */
1089 if (!strncmp (cp
, "include", 7) && isblank (cp
[7]))
1093 while ((dir
= strsep (&cp
, " \t")) != NULL
)
1095 parse_conf_include (filename
, lineno
, do_chroot
, dir
);
1097 else if (!strncasecmp (cp
, "hwcap", 5) && isblank (cp
[5]))
1098 error (0, 0, _("%s:%u: hwcap directive ignored"), filename
, lineno
);
1100 add_dir_1 (cp
, filename
, lineno
);
1102 while (!feof_unlocked (file
));
1104 /* Free buffer and close file. */
1109 /* Handle one word in an `include' line, a glob pattern of additional
1110 config files to read. */
1112 parse_conf_include (const char *config_file
, unsigned int lineno
,
1113 bool do_chroot
, const char *pattern
)
1115 if (opt_chroot
!= NULL
&& pattern
[0] != '/')
1116 error (EXIT_FAILURE
, 0,
1117 _("need absolute file name for configuration file when using -r"));
1120 if (pattern
[0] != '/' && strchr (config_file
, '/') != NULL
)
1122 if (asprintf (©
, "%s/%s", dirname (strdupa (config_file
)),
1124 error (EXIT_FAILURE
, 0, _("memory exhausted"));
1130 if (do_chroot
&& opt_chroot
)
1132 char *canon
= chroot_canon (opt_chroot
, pattern
);
1135 result
= glob64 (canon
, 0, NULL
, &gl
);
1139 result
= glob64 (pattern
, 0, NULL
, &gl
);
1144 for (size_t i
= 0; i
< gl
.gl_pathc
; ++i
)
1145 parse_conf (gl
.gl_pathv
[i
], false);
1157 error (0, errno
, _("%s:%u: cannot read directory %s"),
1158 config_file
, lineno
, pattern
);
1171 main (int argc
, char **argv
)
1173 /* Set locale via LC_ALL. */
1174 setlocale (LC_ALL
, "");
1176 /* But keep the C collation. That way `include' directives using
1177 globbing patterns are processed in a locale-independent order. */
1178 setlocale (LC_COLLATE
, "C");
1180 /* Set the text message domain. */
1181 textdomain (_libc_intl_domainname
);
1183 /* Parse and process arguments. */
1185 argp_parse (&argp
, argc
, argv
, 0, &remaining
, NULL
);
1187 /* Remaining arguments are additional directories if opt_manual_link
1189 if (remaining
!= argc
&& !opt_manual_link
)
1192 for (i
= remaining
; i
< argc
; ++i
)
1193 if (opt_build_cache
&& argv
[i
][0] != '/')
1194 error (EXIT_FAILURE
, 0,
1195 _("relative path `%s' used to build cache"),
1198 add_dir_1 (argv
[i
], "<cmdline>", 0);
1201 if (opt_chroot
!= NULL
)
1203 /* Normalize the path a bit, we might need it for printing later. */
1204 char *endp
= strchr (opt_chroot
, '\0');
1205 while (endp
> opt_chroot
&& endp
[-1] == '/')
1208 if (endp
== opt_chroot
)
1211 if (opt_chroot
!= NULL
)
1213 /* It is faster to use chroot if we can. */
1214 if (!chroot (opt_chroot
))
1217 error (EXIT_FAILURE
, errno
, _("Can't chdir to /"));
1223 if (cache_file
== NULL
)
1225 cache_file
= alloca (strlen (LD_SO_CACHE
) + 1);
1226 strcpy (cache_file
, LD_SO_CACHE
);
1229 if (config_file
== NULL
)
1230 config_file
= LD_SO_CONF
;
1232 if (opt_print_cache
)
1234 if (opt_chroot
!= NULL
)
1236 char *p
= chroot_canon (opt_chroot
, cache_file
);
1238 error (EXIT_FAILURE
, errno
, _("Can't open cache file %s\n"),
1242 print_cache (cache_file
);
1243 if (opt_chroot
!= NULL
)
1248 if (opt_chroot
!= NULL
)
1250 /* Canonicalize the directory name of cache_file, not cache_file,
1251 because we'll rename a temporary cache file to it. */
1252 char *p
= strrchr (cache_file
, '/');
1253 char *canon
= chroot_canon (opt_chroot
,
1254 p
? (*p
= '\0', cache_file
) : "/");
1257 error (EXIT_FAILURE
, errno
,
1258 _("Can't open cache file directory %s\n"),
1259 p
? cache_file
: "/");
1266 cache_file
= alloca (strlen (canon
) + strlen (p
) + 2);
1267 sprintf (cache_file
, "%s/%s", canon
, p
);
1271 if (opt_manual_link
)
1273 /* Link all given libraries manually. */
1276 for (i
= remaining
; i
< argc
; ++i
)
1277 manual_link (argv
[i
]);
1283 if (opt_build_cache
)
1286 if (!opt_only_cline
)
1288 parse_conf (config_file
, true);
1290 /* Always add the standard search paths. */
1291 add_system_dir (SLIBDIR
);
1292 if (strcmp (SLIBDIR
, LIBDIR
))
1293 add_system_dir (LIBDIR
);
1296 const char *aux_cache_file
= _PATH_LDCONFIG_AUX_CACHE
;
1297 if (opt_chroot
!= NULL
)
1298 aux_cache_file
= chroot_canon (opt_chroot
, aux_cache_file
);
1300 if (! opt_ignore_aux_cache
&& aux_cache_file
)
1301 load_aux_cache (aux_cache_file
);
1307 if (opt_build_cache
)
1309 save_cache (cache_file
);
1311 save_aux_cache (aux_cache_file
);