This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: PATCH: Handle symlink to directory in ldconfig.


On Mon, May 07, 2001 at 08:34:37PM +0200, Andreas Jaeger wrote:
> 
> Please use error (EXIT_FAILURE,...) instead of the exit (1).
> 

Thanks. Here is the new one.


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:49:38 2001
@@ -264,13 +264,22 @@ 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 (EXIT_FAILURE, errno, _("Fatal error: can't stat %s"),
+	       ptr->path);
+
+      if (stat64 (entry->path, &stat_buf2))
+	error (EXIT_FAILURE, errno, _("Fatal error: can't stat %s"),
+	       entry->path);
+
+      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 +586,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 +666,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 +702,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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]