]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 30 Sep 2000 00:54:42 +0000 (00:54 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 30 Sep 2000 00:54:42 +0000 (00:54 +0000)
2000-09-29  Ulrich Drepper  <drepper@redhat.com>

* elf/chroot_canon.c: Don't report a failure if the last path
component is not available.
* elf/ldconfig.c (parse_conf): Use canonicalized name when reporting
error.

* elf/cache.c (print_cache): Use stat64 instead of stat.
* elf/ldconfig.c (chroot_stat): Likewise.
(create_links): Likewise.
(manual_link): Likewise.
(search_dir): Likewise.
* elf/readlib.c (process_file): Likewise.

* Makefile (install): Set LC_ALL and LANGUAGE to C before running
ldconfig.

2000-09-29  Jakub Jelinek  <jakub@redhat.com>

* elf/chroot_canon.c: New file.
* elf/Makefile: Build and distribute it.
* elf/ldconfig.h (process_file): Add real_file_name argument.
(chroot_canon): Add prototype.
* elf/ldconfig.c (cache_file): Remove const.
(chroot_stat): New.
(create_links): Add real_path argument.
If opt_chroot, maintain both real and given filenames.
(manual_link): Likewise.
(search_dir): Likewise.
(parse_conf): If opt_chroot, use chroot_canon to find the real
config file.
(main): For -r, try to use chroot, if it fails, leave opt_chroot set
and use chroot_canon where appropriate to do the same as if chroot
succeeded.
* elf/readlib.c (process_file): Add real_file_name argument, pass it
to fopen.

2000-09-29  Ulrich Drepper  <drepper@redhat.com>

* math/complex.h (_Complex): We can be more specific when _Complex
is defined by the compiler.

ChangeLog
Makefile
elf/Makefile
elf/cache.c
elf/chroot_canon.c [new file with mode: 0644]
elf/ldconfig.c
elf/ldconfig.h
elf/readlib.c
math/complex.h

index 34fdb8da58a0cb89ca6ecc8acb1faa097857d583..5414467ed38fe65780a13299e201d37190e5c95e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2000-09-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/chroot_canon.c: Don't report a failure if the last path
+       component is not available.
+       * elf/ldconfig.c (parse_conf): Use canonicalized name when reporting
+       error.
+
+       * elf/cache.c (print_cache): Use stat64 instead of stat.
+       * elf/ldconfig.c (chroot_stat): Likewise.
+       (create_links): Likewise.
+       (manual_link): Likewise.
+       (search_dir): Likewise.
+       * elf/readlib.c (process_file): Likewise.
+
+       * Makefile (install): Set LC_ALL and LANGUAGE to C before running
+       ldconfig.
+
+2000-09-29  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/chroot_canon.c: New file.
+       * elf/Makefile: Build and distribute it.
+       * elf/ldconfig.h (process_file): Add real_file_name argument.
+       (chroot_canon): Add prototype.
+       * elf/ldconfig.c (cache_file): Remove const.
+       (chroot_stat): New.
+       (create_links): Add real_path argument.
+       If opt_chroot, maintain both real and given filenames.
+       (manual_link): Likewise.
+       (search_dir): Likewise.
+       (parse_conf): If opt_chroot, use chroot_canon to find the real
+       config file.
+       (main): For -r, try to use chroot, if it fails, leave opt_chroot set
+       and use chroot_canon where appropriate to do the same as if chroot
+       succeeded.
+       * elf/readlib.c (process_file): Add real_file_name argument, pass it
+       to fopen.
+
+2000-09-29  Ulrich Drepper  <drepper@redhat.com>
+
+       * math/complex.h (_Complex): We can be more specific when _Complex
+       is defined by the compiler.
+
 2000-09-29  H.J. Lu  <hjl@gnu.org>
 
        * sysdeps/unix/sysv/linux/ia64/dl-cache.h: New.
index 6da6df0dde9bd5370be706c1f2bd6f7135486f7d..04a17083514e9c898f10ab5b57c6734f575ee7c5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -108,7 +108,7 @@ install-symbolic-link: subdir_install
        rm -f $(symbolic-link-list)
 
 install:
-       -test ! -x $(common-objpfx)elf/ldconfig || \
+       -test ! -x $(common-objpfx)elf/ldconfig || LC_ALL=C LANGUAGE=C \
          $(common-objpfx)elf/ldconfig $(addprefix -r ,$(install_root)) \
                                       $(slibdir) $(libdir)
 ifneq (no,$(PERL))
index 84815b30eaf0460190b288c4c71b47432ef22973..4d786ec3abd6adffd61235d26df18afc2becdd6f 100644 (file)
@@ -46,6 +46,7 @@ distribute    := $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
                   testobj1.c testobj2.c testobj3.c testobj4.c testobj5.c \
                   testobj6.c testobj1_1.c failobj.c unloadmod.c \
                   ldconfig.h ldconfig.c cache.c readlib.c readelflib.c \
+                  chroot_canon.c \
                   dep1.c dep2.c dep3.c dep4.c dl-dtprocnum.h unsecvars.h \
                   vismain.c vismod1.c vismod2.c vismod3.c \
                   constload2.c constload3.c filtmod1.c filtmod2.c \
@@ -81,7 +82,7 @@ others-static += ldconfig
 others         += ldconfig
 install-rootsbin += ldconfig
 
-ldconfig-modules := cache readlib xmalloc xstrdup
+ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon
 extra-objs     += $(ldconfig-modules:=.o)
 
 # To find xmalloc.c and xstrdup.c
index ef0248f4f8e0e42049fb04f6b71b7f019b400149..b84287332e44fab704ae0b4e2548e5c190308600 100644 (file)
@@ -94,7 +94,7 @@ void
 print_cache (const char *cache_name)
 {
   size_t cache_size;
-  struct stat st;
+  struct stat64 st;
   int fd;
   unsigned int i;
   struct cache_file *cache;
@@ -106,7 +106,7 @@ print_cache (const char *cache_name)
   if (fd < 0)
     error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name);
 
-  if (fstat (fd, &st) < 0
+  if (fstat64 (fd, &st) < 0
       /* No need to map the file if it is empty.  */
       || st.st_size == 0)
     {
diff --git a/elf/chroot_canon.c b/elf/chroot_canon.c
new file mode 100644 (file)
index 0000000..82cb8c4
--- /dev/null
@@ -0,0 +1,172 @@
+/* Return the canonical absolute name of a given file inside chroot.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stddef.h>
+#include "ldconfig.h"
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+/* Return the canonical absolute name of file NAME as if chroot(CHROOT) was
+   done first.  A canonical name does not contain any `.', `..' components
+   nor any repeated path separators ('/') or symlinks.  All path components
+   must exist and NAME must be absolute filename.  The result is malloc'd.
+   The returned name includes the CHROOT prefix.  */
+
+char *
+chroot_canon (const char *chroot, const char *name)
+{
+  char *rpath, *dest, *extra_buf = NULL, *rpath_root;
+  const char *start, *end, *rpath_limit;
+  int num_links = 0;
+  size_t chroot_len = strlen (chroot);
+
+  if (chroot_len < 1)
+    {
+      __set_errno (EINVAL);
+      return NULL;
+    }
+
+  rpath = malloc (chroot_len + PATH_MAX);
+  rpath_limit = rpath + chroot_len + PATH_MAX;
+
+  rpath_root = (char *) mempcpy (rpath, chroot, chroot_len) - 1;
+  if (*rpath_root != '/')
+    *++rpath_root = '/';
+  dest = rpath_root + 1;
+
+  for (start = end = name; *start; start = end)
+    {
+      struct stat64 st;
+      int n;
+
+      /* Skip sequence of multiple path-separators.  */
+      while (*start == '/')
+       ++start;
+
+      /* Find end of path component.  */
+      for (end = start; *end && *end != '/'; ++end)
+       /* Nothing.  */;
+
+      if (end - start == 0)
+       break;
+      else if (end - start == 1 && start[0] == '.')
+       /* nothing */;
+      else if (end - start == 2 && start[0] == '.' && start[1] == '.')
+       {
+         /* Back up to previous component, ignore if at root already.  */
+         if (dest > rpath_root + 1)
+           while ((--dest)[-1] != '/');
+       }
+      else
+       {
+         size_t new_size;
+
+         if (dest[-1] != '/')
+           *dest++ = '/';
+
+         if (dest + (end - start) >= rpath_limit)
+           {
+             ptrdiff_t dest_offset = dest - rpath;
+
+             new_size = rpath_limit - rpath;
+             if (end - start + 1 > PATH_MAX)
+               new_size += end - start + 1;
+             else
+               new_size += PATH_MAX;
+             rpath = realloc (rpath, new_size);
+             rpath_limit = rpath + new_size;
+             if (rpath == NULL)
+               return NULL;
+
+             dest = rpath + dest_offset;
+           }
+
+         dest = mempcpy (dest, start, end - start);
+         *dest = '\0';
+
+         if (lstat64 (rpath, &st) < 0)
+           {
+             if (*end == '\0')
+               goto done;
+             goto error;
+           }
+
+         if (S_ISLNK (st.st_mode))
+           {
+             char *buf = alloca (PATH_MAX);
+             size_t len;
+
+             if (++num_links > MAXSYMLINKS)
+               {
+                 __set_errno (ELOOP);
+                 goto error;
+               }
+
+             n = readlink (rpath, buf, PATH_MAX);
+             if (n < 0)
+               {
+                 if (*end == '\0')
+                   goto done;
+                 goto error;
+               }
+             buf[n] = '\0';
+
+             if (!extra_buf)
+               extra_buf = alloca (PATH_MAX);
+
+             len = strlen (end);
+             if ((long int) (n + len) >= PATH_MAX)
+               {
+                 __set_errno (ENAMETOOLONG);
+                 goto error;
+               }
+
+             /* Careful here, end may be a pointer into extra_buf... */
+             memmove (&extra_buf[n], end, len + 1);
+             name = end = memcpy (extra_buf, buf, n);
+
+             if (buf[0] == '/')
+               dest = rpath_root + 1;  /* It's an absolute symlink */
+             else
+               /* Back up to previous component, ignore if at root already: */
+               if (dest > rpath_root + 1)
+                 while ((--dest)[-1] != '/');
+           }
+       }
+    }
+ done:
+  if (dest > rpath_root + 1 && dest[-1] == '/')
+    --dest;
+  *dest = '\0';
+
+  return rpath;
+
+ error:
+  free (rpath);
+  return NULL;
+}
index 9202567a10a79b46cf6a4a719564f90b3316007f..2e8746e75cdc2eb3b4952c7c5767a609774ba8ad 100644 (file)
@@ -110,7 +110,7 @@ static char *opt_chroot;
 static int opt_manual_link = 0;
 
 /* Cache file to use.  */
-static const char *cache_file;
+static char *cache_file;
 
 /* Configuration file.  */
 static const char *config_file;
@@ -334,12 +334,36 @@ add_dir (const char *line)
 }
 
 
+static int
+chroot_stat (const char *real_path, const char *path, struct stat64 *st)
+{
+  int ret;
+  char *canon_path;
+
+  if (!opt_chroot)
+    return stat64 (real_path, st);
+
+  ret = lstat64 (real_path, st);
+  if (ret || !S_ISLNK (st->st_mode))
+    return ret;
+
+  canon_path = chroot_canon (opt_chroot, path);
+  if (canon_path == NULL)
+    return -1;
+
+  ret = stat64 (canon_path, st);
+  free (canon_path);
+  return ret;
+}
+
 /* Create a symbolic link from soname to libname in directory path.  */
 static void
-create_links (const char *path, const char *libname, const char *soname)
+create_links (const char *real_path, const char *path, const char *libname,
+             const char *soname)
 {
   char *full_libname, *full_soname;
-  struct stat stat_lib, stat_so, lstat_so;
+  char *real_full_libname, *real_full_soname;
+  struct stat64 stat_lib, stat_so, lstat_so;
   int do_link = 1;
   int do_remove = 1;
   /* XXX: The logics in this function should be simplified.  */
@@ -349,11 +373,23 @@ create_links (const char *path, const char *libname, const char *soname)
   full_soname = alloca (strlen (path) + strlen (libname) + 2);
   sprintf (full_libname, "%s/%s", path, libname);
   sprintf (full_soname, "%s/%s", path, soname);
+  if (opt_chroot)
+    {
+      real_full_libname = alloca (strlen (real_path) + strlen (libname) + 2);
+      real_full_soname = alloca (strlen (real_path) + strlen (libname) + 2);
+      sprintf (real_full_libname, "%s/%s", real_path, libname);
+      sprintf (real_full_soname, "%s/%s", real_path, soname);
+    }
+  else
+    {
+      real_full_libname = full_libname;
+      real_full_soname = full_soname;
+    }
 
   /* Does soname already exist and point to the right library?  */
-  if (stat (full_soname, &stat_so) == 0)
+  if (chroot_stat (real_full_soname, full_soname, &stat_so) == 0)
     {
-      if (stat (full_libname, &stat_lib))
+      if (chroot_stat (real_full_libname, full_libname, &stat_lib))
        {
          error (0, 0, _("Can't stat %s\n"), full_libname);
          return;
@@ -362,7 +398,7 @@ create_links (const char *path, const char *libname, const char *soname)
          && stat_lib.st_ino == stat_so.st_ino)
        /* Link is already correct.  */
        do_link = 0;
-      else if (lstat (full_soname, &lstat_so) == 0
+      else if (lstat64 (full_soname, &lstat_so) == 0
               && !S_ISLNK (lstat_so.st_mode))
        {
          error (0, 0, _("%s is not a symbolic link\n"), full_soname);
@@ -370,7 +406,7 @@ create_links (const char *path, const char *libname, const char *soname)
          do_remove = 0;
        }
     }
-  else if (lstat (full_soname, &lstat_so) != 0
+  else if (lstat64 (real_full_soname, &lstat_so) != 0
           || !S_ISLNK (lstat_so.st_mode))
     /* Unless it is a stale symlink, there is no need to remove.  */
     do_remove = 0;
@@ -382,13 +418,13 @@ create_links (const char *path, const char *libname, const char *soname)
     {
       /* Remove old link.  */
       if (do_remove)
-       if (unlink (full_soname))
+       if (unlink (real_full_soname))
          {
            error (0, 0, _("Can't unlink %s"), full_soname);
            do_link = 0;
          }
       /* Create symbolic link.  */
-      if (do_link && symlink (libname, full_soname))
+      if (do_link && symlink (libname, real_full_soname))
        {
          error (0, 0, _("Can't link %s to %s"), full_soname, libname);
          do_link = 0;
@@ -410,9 +446,11 @@ static void
 manual_link (char *library)
 {
   char *path;
+  char *real_path;
+  char *real_library;
   char *libname;
   char *soname;
-  struct stat stat_buf;
+  struct stat64 stat_buf;
   int flag;
 
   /* Prepare arguments for create_links call.  Split library name in
@@ -445,8 +483,26 @@ manual_link (char *library)
       strcpy (path, ".");
     }
 
+  if (opt_chroot)
+    {
+      real_path = chroot_canon (opt_chroot, path);
+      if (real_path == NULL)
+       {
+         error (0, errno, _("Can't find %s"), path);
+         free (path);
+         return;
+       }
+      real_library = alloca (strlen (real_path) + strlen (libname) + 2);
+      sprintf (real_library, "%s/%s", real_path, libname);
+    }
+  else
+    {
+      real_path = path;
+      real_library = library;
+    }
+
   /* Do some sanity checks first.  */
-  if (lstat (library, &stat_buf))
+  if (lstat64 (real_library, &stat_buf))
     {
       error (0, errno, _("Can't lstat %s"), library);
       free (path);
@@ -460,15 +516,14 @@ manual_link (char *library)
       free (path);
       return;
     }
-  libname = basename (library);
-  if (process_file (library, libname, &flag, &soname, 0))
+  if (process_file (real_library, library, libname, &flag, &soname, 0))
     {
       error (0, 0, _("No link created since soname could not be found for %s"),
             library);
       free (path);
       return;
     }
-  create_links (path, libname, soname);
+  create_links (real_path, path, libname, soname);
   free (soname);
   free (path);
 }
@@ -514,12 +569,12 @@ search_dir (const struct dir_entry *entry)
 {
   DIR *dir;
   struct dirent *direntry;
-  char *file_name;
-  int file_name_len, len;
+  char *file_name, *dir_name, *real_file_name, *real_name;
+  int file_name_len, real_file_name_len, len;
   char *soname;
   struct dlib_entry *dlibs;
   struct dlib_entry *dlib_ptr;
-  struct stat stat_buf;
+  struct stat64 stat_buf;
   int is_link;
   unsigned long int hwcap = path_hwcap (entry->path);
 
@@ -536,15 +591,28 @@ search_dir (const struct dir_entry *entry)
        printf ("%s:\n", entry->path);
     }
 
-  dir = opendir (entry->path);
-  if (dir == NULL)
+  if (opt_chroot)
+    {
+      dir_name = chroot_canon (opt_chroot, entry->path);
+      real_file_name_len = PATH_MAX;
+      real_file_name = alloca (real_file_name_len);
+    }
+  else
+    {
+      dir_name = entry->path;
+      real_file_name_len = 0;
+      real_file_name = file_name;
+    }
+
+  if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
     {
       if (opt_verbose)
        error (0, errno, _("Can't open directory %s"), entry->path);
+      if (opt_chroot && dir_name)
+       free (dir_name);
       return;
     }
 
-
   while ((direntry = readdir (dir)) != NULL)
     {
       int flag;
@@ -569,14 +637,26 @@ search_dir (const struct dir_entry *entry)
        {
          file_name_len = len + 1;
          file_name = alloca (file_name_len);
+         if (!opt_chroot)
+           real_file_name = file_name;
+       }
+      sprintf (file_name, "%s/%s", entry->path, direntry->d_name);
+      if (opt_chroot)
+       {
+         len = strlen (dir_name) + strlen (direntry->d_name);
+         if (len > real_file_name_len)
+           {
+             real_file_name_len = len + 1;
+             real_file_name = alloca (real_file_name_len);
+           }
+         sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
        }
-      sprintf (file_name , "%s/%s", entry->path, direntry->d_name);
 #ifdef _DIRENT_HAVE_D_TYPE
       if (direntry->d_type != DT_UNKNOWN)
        stat_buf.st_mode = DTTOIF (direntry->d_type);
       else
 #endif
-       if (lstat (file_name, &stat_buf))
+       if (lstat64 (real_file_name, &stat_buf))
          {
            error (0, errno, _("Can't lstat %s"), file_name);
            continue;
@@ -598,9 +678,29 @@ search_dir (const struct dir_entry *entry)
        continue;
 
       is_link = S_ISLNK (stat_buf.st_mode);
+      if (opt_chroot && is_link)
+       {
+         real_name = chroot_canon (opt_chroot, file_name);
+         if (real_name == NULL)
+           {
+             if (strstr (file_name, ".so") == NULL)
+               error (0, 0, _("Input file %s not found.\n"), file_name);
+             continue;
+           }
+       }
+      else
+       real_name = real_file_name;
 
-      if (process_file (file_name, direntry->d_name, &flag, &soname, is_link))
-       continue;
+      if (process_file (real_name, file_name, direntry->d_name, &flag,
+                       &soname, is_link))
+       {
+         if (real_name != real_file_name)
+           free (real_name);
+         continue;
+       }
+
+      if (real_name != real_file_name)
+       free (real_name);
 
       /* Links will just point to itself.  */
       if (is_link)
@@ -686,7 +786,8 @@ search_dir (const struct dir_entry *entry)
     {
       /* Don't create links to links.  */
       if (dlib_ptr->is_link == 0)
-       create_links (entry->path, dlib_ptr->name, dlib_ptr->soname);
+       create_links (dir_name, entry->path, dlib_ptr->name,
+                     dlib_ptr->soname);
       if (opt_build_cache)
        add_to_cache (entry->path, dlib_ptr->soname, dlib_ptr->flag, hwcap);
     }
@@ -700,6 +801,9 @@ search_dir (const struct dir_entry *entry)
       dlibs = dlibs->next;
       free (dlib_ptr);
     }
+
+  if (opt_chroot && dir_name)
+    free (dir_name);
 }
 
 /* Search through all libraries.  */
@@ -726,19 +830,36 @@ search_dirs (void)
 static void
 parse_conf (const char *filename)
 {
-  FILE *file;
+  FILE *file = NULL;
   char *line = NULL;
+  const char *canon;
   size_t len = 0;
 
-  file = fopen (filename, "r");
+  if (opt_chroot)
+    {
+      canon = chroot_canon (opt_chroot, filename);
+      if (canon)
+       file = fopen (canon, "r");
+      else
+       canon = filename;
+    }
+  else
+    {
+      canon = filename;
+      file = fopen (filename, "r");
+    }
 
   if (file == NULL)
     {
-      error (0, errno, _("Can't open configuration file %s%s%s"),
-            opt_chroot ?: "", opt_chroot ? "/" : "", filename);
+      error (0, errno, _("Can't open configuration file %s"), canon);
+      if (canon != filename)
+       free ((char *) canon);
       return;
     }
 
+  if (canon != filename)
+    free ((char *) canon);
+
   do
     {
       ssize_t n = getline (&line, &len, file);
@@ -783,35 +904,78 @@ main (int argc, char **argv)
        add_dir (argv [i]);
     }
 
-  if (cache_file == NULL)
-    cache_file = LD_SO_CACHE;
-
-  if (config_file == NULL)
-    config_file = LD_SO_CONF;
-
-  /* Chroot first.  */
   if (opt_chroot)
     {
       /* Normalize the path a bit, we might need it for printing later.  */
       char *endp = strchr (opt_chroot, '\0');
-      while (endp > opt_chroot + 1 && endp[-1] == '/')
+      while (endp > opt_chroot && endp[-1] == '/')
        --endp;
       *endp = '\0';
+      if (endp == opt_chroot)
+       opt_chroot = NULL;
 
-      if (chroot (opt_chroot))
-       /* Report failure and exit program.  */
-       error (EXIT_FAILURE, errno, _("Can't chroot to %s"), opt_chroot);
-      /* chroot doesn't change the working directory, let's play safe.  */
-      if (chdir ("/"))
-       error (EXIT_FAILURE, errno, _("Can't chdir to /"));
+      if (opt_chroot)
+       {
+         /* It is faster to use chroot if we can.  */
+         if (!chroot (opt_chroot))
+           {
+             if (chdir ("/"))
+               error (EXIT_FAILURE, errno, _("Can't chdir to /"));
+             opt_chroot = NULL;
+           }
+       }
+    }
+
+  if (cache_file == NULL)
+    {
+      cache_file = alloca (strlen (LD_SO_CACHE) + 1);
+      strcpy (cache_file, LD_SO_CACHE);
     }
 
+  if (config_file == NULL)
+    config_file = LD_SO_CONF;
+
   if (opt_print_cache)
     {
+      if (opt_chroot)
+       {
+         char *p = chroot_canon (opt_chroot, cache_file);
+         if (p == NULL)
+           error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
+                  cache_file);
+         cache_file = p;
+       }
       print_cache (cache_file);
+      if (opt_chroot)
+       free (cache_file);
       exit (0);
     }
 
+  if (opt_chroot)
+    {
+      /* Canonicalize the directory name of cache_file, not cache_file,
+         because we'll rename a temporary cache file to it.  */
+      char *p = strrchr (cache_file, '/');
+      char *canon = chroot_canon (opt_chroot,
+                                 p ? (*p = '\0', cache_file) : "/");
+
+      if (canon == NULL)
+       {
+         error (EXIT_FAILURE, errno,
+                _("Can't open cache file directory %s\n"),
+                p ? cache_file : "/");
+       }
+
+      if (p)
+       ++p;
+      else
+       p = cache_file;
+
+      cache_file = alloca (strlen (canon) + strlen (p) + 2);
+      sprintf (cache_file, "%s/%s", canon, p);
+      free (canon);
+    }
+
   if (opt_manual_link)
     {
       /* Link all given libraries manually.  */
index a94df64ad051966f7493422014192f3638fe17cb..76284f6e67e7420df1a52d96adb07066d3203e47 100644 (file)
@@ -41,14 +41,17 @@ extern void add_to_cache (const char *path, const char *lib, int flags,
                          unsigned long int hwcap);
 
 /* Declared in readlib.c.  */
-extern int process_file (const char *file_name, const char *lib, int *flag,
-                        char **soname, int is_link);
+extern int process_file (const char *real_file_name, const char *file_name,
+                        const char *lib, int *flag, char **soname,
+                        int is_link);
 
 /* Declared in readelflib.c.  */
 extern int process_elf_file (const char *file_name, const char *lib, int *flag,
                             char **soname, void *file_contents,
                             size_t file_length);
 
+/* Declared in chroot_canon.c.  */
+extern char *chroot_canon (const char *chroot, const char *name);
 
 /* Declared in ldconfig.c.  */
 extern int opt_verbose;
index 5ec5a546be10c5125e34b94b1f16ca866deb2eb0..70a77e2e720f774469cab9981900e1b5e340ab30 100644 (file)
@@ -68,11 +68,11 @@ static struct known_names known_libs [] =
 
 /* Returns 0 if everything is ok, != 0 in case of error.  */
 int
-process_file (const char *file_name, const char *lib, int *flag,
-             char **soname, int is_link)
+process_file (const char *real_file_name, const char *file_name,
+             const char *lib, int *flag, char **soname, int is_link)
 {
   FILE *file;
-  struct stat statbuf;
+  struct stat64 statbuf;
   void *file_contents;
   int ret;
 
@@ -83,7 +83,7 @@ process_file (const char *file_name, const char *lib, int *flag,
   *flag = FLAG_ANY;
   *soname = NULL;
 
-  file = fopen (file_name, "rb");
+  file = fopen (real_file_name, "rb");
   if (file == NULL)
     {
       /* No error for stale symlink.  */
@@ -93,7 +93,7 @@ process_file (const char *file_name, const char *lib, int *flag,
       return 1;
     }
 
-  if (fstat (fileno (file), &statbuf) < 0)
+  if (fstat64 (fileno (file), &statbuf) < 0)
     {
       error (0, 0, _("Cannot fstat file %s.\n"), file_name);
       fclose (file);
index ac08875adcd570881e5d1cd79fa3051afd95a7e4..dda34ec19d4a1158e0354d0595a79c7db0d75e97 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -33,7 +33,7 @@ __BEGIN_DECLS
 /* We might need to add support for more compilers here.  But since ISO
    C99 is out hopefully all maintained compilers will soon provide the data
    types `float complex' and `double complex'.  */
-#if __GNUC_PREREQ (2, 7) && !__GNUC_PREREQ (3, 0)
+#if __GNUC_PREREQ (2, 7) && !__GNUC_PREREQ (2, 97)
 # define _Complex __complex__
 #endif