This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
PATCH: Handle symlink to directory in ldconfig.
- To: GNU C Library <libc-alpha at sourceware dot cygnus dot com>
- Subject: PATCH: Handle symlink to directory in ldconfig.
- From: "H . J . Lu" <hjl at lucon dot org>
- Date: Mon, 7 May 2001 11:20:25 -0700
This patch for ldconfig handls symlink to directory.
H.J.
---
2001-05-07 H.J. Lu <hjl@gnu.org>
* elf/ldconfig.c (add_single_dir): Call stat to check if 2
directory paths point to the same inode or not.
(search_dir): Handle symlink to directory.
--- libc/elf/ldconfig.c.link Mon Mar 19 10:36:17 2001
+++ libc/elf/ldconfig.c Mon May 7 11:10:15 2001
@@ -264,13 +264,24 @@ static void
add_single_dir (struct dir_entry *entry, int verbose)
{
struct dir_entry *ptr, *prev;
+ struct stat64 stat_buf1, stat_buf2;
ptr = dir_entries;
prev = ptr;
while (ptr != NULL)
{
/* Check for duplicates. */
- if (strcmp (ptr->path, entry->path) == 0)
+ if (stat64 (ptr->path, &stat_buf1))
+ {
+ error (0, errno, _("Fatal error: can't stat %s"), ptr->path);
+ exit (1);
+ }
+ if (stat64 (entry->path, &stat_buf2))
+ {
+ error (0, errno, _("Fatal error: can't stat %s"), entry->path);
+ exit (1);
+ }
+ if (memcmp (&stat_buf1, &stat_buf2, sizeof (stat_buf1)) == 0)
{
if (opt_verbose && verbose)
error (0, 0, _("Path `%s' given more than once"), entry->path);
@@ -577,8 +588,8 @@ search_dir (const struct dir_entry *entr
char *soname;
struct dlib_entry *dlibs;
struct dlib_entry *dlib_ptr;
- struct stat64 stat_buf;
- int is_link;
+ struct stat64 lstat_buf, stat_buf;
+ int is_link, is_dir;
uint64_t hwcap = path_hwcap (entry->path);
unsigned int osversion;
@@ -657,16 +668,31 @@ search_dir (const struct dir_entry *entr
}
#ifdef _DIRENT_HAVE_D_TYPE
if (direntry->d_type != DT_UNKNOWN)
- stat_buf.st_mode = DTTOIF (direntry->d_type);
+ lstat_buf.st_mode = DTTOIF (direntry->d_type);
else
#endif
- if (lstat64 (real_file_name, &stat_buf))
+ if (lstat64 (real_file_name, &lstat_buf))
{
error (0, errno, _("Can't lstat %s"), file_name);
continue;
}
- if (S_ISDIR (stat_buf.st_mode) && is_hwcap_platform (direntry->d_name))
+ is_link = S_ISLNK (lstat_buf.st_mode);
+ if (is_link)
+ {
+ /* In case of symlink, we check if the symlink refers to
+ a directory. */
+ if (stat64 (real_file_name, &stat_buf))
+ {
+ error (0, errno, _("Can't stat %s"), file_name);
+ continue;
+ }
+ is_dir = S_ISDIR (stat_buf.st_mode);
+ }
+ else
+ is_dir = S_ISDIR (lstat_buf.st_mode);
+
+ if (is_dir && is_hwcap_platform (direntry->d_name))
{
/* Handle subdirectory later. */
struct dir_entry *new_entry;
@@ -678,10 +704,9 @@ search_dir (const struct dir_entry *entr
add_single_dir (new_entry, 0);
continue;
}
- else if (!S_ISREG (stat_buf.st_mode) && !S_ISLNK (stat_buf.st_mode))
+ else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
continue;
- is_link = S_ISLNK (stat_buf.st_mode);
if (opt_chroot && is_link)
{
real_name = chroot_canon (opt_chroot, file_name);