1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00
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.
This commit is contained in:
Ulrich Drepper
2000-09-30 00:54:42 +00:00
parent 955821742e
commit b4a555d6f4
9 changed files with 438 additions and 56 deletions

View File

@ -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> 2000-09-29 H.J. Lu <hjl@gnu.org>
* sysdeps/unix/sysv/linux/ia64/dl-cache.h: New. * sysdeps/unix/sysv/linux/ia64/dl-cache.h: New.

View File

@ -108,7 +108,7 @@ install-symbolic-link: subdir_install
rm -f $(symbolic-link-list) rm -f $(symbolic-link-list)
install: 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)) \ $(common-objpfx)elf/ldconfig $(addprefix -r ,$(install_root)) \
$(slibdir) $(libdir) $(slibdir) $(libdir)
ifneq (no,$(PERL)) ifneq (no,$(PERL))

View 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 \ testobj1.c testobj2.c testobj3.c testobj4.c testobj5.c \
testobj6.c testobj1_1.c failobj.c unloadmod.c \ testobj6.c testobj1_1.c failobj.c unloadmod.c \
ldconfig.h ldconfig.c cache.c readlib.c readelflib.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 \ dep1.c dep2.c dep3.c dep4.c dl-dtprocnum.h unsecvars.h \
vismain.c vismod1.c vismod2.c vismod3.c \ vismain.c vismod1.c vismod2.c vismod3.c \
constload2.c constload3.c filtmod1.c filtmod2.c \ constload2.c constload3.c filtmod1.c filtmod2.c \
@ -81,7 +82,7 @@ others-static += ldconfig
others += ldconfig others += ldconfig
install-rootsbin += ldconfig install-rootsbin += ldconfig
ldconfig-modules := cache readlib xmalloc xstrdup ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon
extra-objs += $(ldconfig-modules:=.o) extra-objs += $(ldconfig-modules:=.o)
# To find xmalloc.c and xstrdup.c # To find xmalloc.c and xstrdup.c

View File

@ -94,7 +94,7 @@ void
print_cache (const char *cache_name) print_cache (const char *cache_name)
{ {
size_t cache_size; size_t cache_size;
struct stat st; struct stat64 st;
int fd; int fd;
unsigned int i; unsigned int i;
struct cache_file *cache; struct cache_file *cache;
@ -106,7 +106,7 @@ print_cache (const char *cache_name)
if (fd < 0) if (fd < 0)
error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name); 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. */ /* No need to map the file if it is empty. */
|| st.st_size == 0) || st.st_size == 0)
{ {

172
elf/chroot_canon.c Normal file
View File

@ -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;
}

View File

@ -110,7 +110,7 @@ static char *opt_chroot;
static int opt_manual_link = 0; static int opt_manual_link = 0;
/* Cache file to use. */ /* Cache file to use. */
static const char *cache_file; static char *cache_file;
/* Configuration file. */ /* Configuration file. */
static const char *config_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. */ /* Create a symbolic link from soname to libname in directory path. */
static void 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; 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_link = 1;
int do_remove = 1; int do_remove = 1;
/* XXX: The logics in this function should be simplified. */ /* 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); full_soname = alloca (strlen (path) + strlen (libname) + 2);
sprintf (full_libname, "%s/%s", path, libname); sprintf (full_libname, "%s/%s", path, libname);
sprintf (full_soname, "%s/%s", path, soname); 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? */ /* 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); error (0, 0, _("Can't stat %s\n"), full_libname);
return; return;
@ -362,7 +398,7 @@ create_links (const char *path, const char *libname, const char *soname)
&& stat_lib.st_ino == stat_so.st_ino) && stat_lib.st_ino == stat_so.st_ino)
/* Link is already correct. */ /* Link is already correct. */
do_link = 0; 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)) && !S_ISLNK (lstat_so.st_mode))
{ {
error (0, 0, _("%s is not a symbolic link\n"), full_soname); 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; 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)) || !S_ISLNK (lstat_so.st_mode))
/* Unless it is a stale symlink, there is no need to remove. */ /* Unless it is a stale symlink, there is no need to remove. */
do_remove = 0; do_remove = 0;
@ -382,13 +418,13 @@ create_links (const char *path, const char *libname, const char *soname)
{ {
/* Remove old link. */ /* Remove old link. */
if (do_remove) if (do_remove)
if (unlink (full_soname)) if (unlink (real_full_soname))
{ {
error (0, 0, _("Can't unlink %s"), full_soname); error (0, 0, _("Can't unlink %s"), full_soname);
do_link = 0; do_link = 0;
} }
/* Create symbolic link. */ /* 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); error (0, 0, _("Can't link %s to %s"), full_soname, libname);
do_link = 0; do_link = 0;
@ -410,9 +446,11 @@ static void
manual_link (char *library) manual_link (char *library)
{ {
char *path; char *path;
char *real_path;
char *real_library;
char *libname; char *libname;
char *soname; char *soname;
struct stat stat_buf; struct stat64 stat_buf;
int flag; int flag;
/* Prepare arguments for create_links call. Split library name in /* Prepare arguments for create_links call. Split library name in
@ -445,8 +483,26 @@ manual_link (char *library)
strcpy (path, "."); 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. */ /* Do some sanity checks first. */
if (lstat (library, &stat_buf)) if (lstat64 (real_library, &stat_buf))
{ {
error (0, errno, _("Can't lstat %s"), library); error (0, errno, _("Can't lstat %s"), library);
free (path); free (path);
@ -460,15 +516,14 @@ manual_link (char *library)
free (path); free (path);
return; return;
} }
libname = basename (library); if (process_file (real_library, library, libname, &flag, &soname, 0))
if (process_file (library, libname, &flag, &soname, 0))
{ {
error (0, 0, _("No link created since soname could not be found for %s"), error (0, 0, _("No link created since soname could not be found for %s"),
library); library);
free (path); free (path);
return; return;
} }
create_links (path, libname, soname); create_links (real_path, path, libname, soname);
free (soname); free (soname);
free (path); free (path);
} }
@ -514,12 +569,12 @@ search_dir (const struct dir_entry *entry)
{ {
DIR *dir; DIR *dir;
struct dirent *direntry; struct dirent *direntry;
char *file_name; char *file_name, *dir_name, *real_file_name, *real_name;
int file_name_len, len; int file_name_len, real_file_name_len, len;
char *soname; char *soname;
struct dlib_entry *dlibs; struct dlib_entry *dlibs;
struct dlib_entry *dlib_ptr; struct dlib_entry *dlib_ptr;
struct stat stat_buf; struct stat64 stat_buf;
int is_link; int is_link;
unsigned long int hwcap = path_hwcap (entry->path); unsigned long int hwcap = path_hwcap (entry->path);
@ -536,15 +591,28 @@ search_dir (const struct dir_entry *entry)
printf ("%s:\n", entry->path); printf ("%s:\n", entry->path);
} }
dir = opendir (entry->path); if (opt_chroot)
if (dir == NULL) {
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) if (opt_verbose)
error (0, errno, _("Can't open directory %s"), entry->path); error (0, errno, _("Can't open directory %s"), entry->path);
if (opt_chroot && dir_name)
free (dir_name);
return; return;
} }
while ((direntry = readdir (dir)) != NULL) while ((direntry = readdir (dir)) != NULL)
{ {
int flag; int flag;
@ -569,14 +637,26 @@ search_dir (const struct dir_entry *entry)
{ {
file_name_len = len + 1; file_name_len = len + 1;
file_name = alloca (file_name_len); 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 #ifdef _DIRENT_HAVE_D_TYPE
if (direntry->d_type != DT_UNKNOWN) if (direntry->d_type != DT_UNKNOWN)
stat_buf.st_mode = DTTOIF (direntry->d_type); stat_buf.st_mode = DTTOIF (direntry->d_type);
else else
#endif #endif
if (lstat (file_name, &stat_buf)) if (lstat64 (real_file_name, &stat_buf))
{ {
error (0, errno, _("Can't lstat %s"), file_name); error (0, errno, _("Can't lstat %s"), file_name);
continue; continue;
@ -598,9 +678,29 @@ search_dir (const struct dir_entry *entry)
continue; continue;
is_link = S_ISLNK (stat_buf.st_mode); 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)) if (process_file (real_name, file_name, direntry->d_name, &flag,
continue; &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. */ /* Links will just point to itself. */
if (is_link) if (is_link)
@ -686,7 +786,8 @@ search_dir (const struct dir_entry *entry)
{ {
/* Don't create links to links. */ /* Don't create links to links. */
if (dlib_ptr->is_link == 0) 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) if (opt_build_cache)
add_to_cache (entry->path, dlib_ptr->soname, dlib_ptr->flag, hwcap); 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; dlibs = dlibs->next;
free (dlib_ptr); free (dlib_ptr);
} }
if (opt_chroot && dir_name)
free (dir_name);
} }
/* Search through all libraries. */ /* Search through all libraries. */
@ -726,19 +830,36 @@ search_dirs (void)
static void static void
parse_conf (const char *filename) parse_conf (const char *filename)
{ {
FILE *file; FILE *file = NULL;
char *line = NULL; char *line = NULL;
const char *canon;
size_t len = 0; 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) if (file == NULL)
{ {
error (0, errno, _("Can't open configuration file %s%s%s"), error (0, errno, _("Can't open configuration file %s"), canon);
opt_chroot ?: "", opt_chroot ? "/" : "", filename); if (canon != filename)
free ((char *) canon);
return; return;
} }
if (canon != filename)
free ((char *) canon);
do do
{ {
ssize_t n = getline (&line, &len, file); ssize_t n = getline (&line, &len, file);
@ -783,35 +904,78 @@ main (int argc, char **argv)
add_dir (argv [i]); 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) if (opt_chroot)
{ {
/* Normalize the path a bit, we might need it for printing later. */ /* Normalize the path a bit, we might need it for printing later. */
char *endp = strchr (opt_chroot, '\0'); char *endp = strchr (opt_chroot, '\0');
while (endp > opt_chroot + 1 && endp[-1] == '/') while (endp > opt_chroot && endp[-1] == '/')
--endp; --endp;
*endp = '\0'; *endp = '\0';
if (endp == opt_chroot)
opt_chroot = NULL;
if (chroot (opt_chroot)) if (opt_chroot)
/* Report failure and exit program. */ {
error (EXIT_FAILURE, errno, _("Can't chroot to %s"), opt_chroot); /* It is faster to use chroot if we can. */
/* chroot doesn't change the working directory, let's play safe. */ if (!chroot (opt_chroot))
if (chdir ("/")) {
error (EXIT_FAILURE, errno, _("Can't chdir to /")); 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_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); print_cache (cache_file);
if (opt_chroot)
free (cache_file);
exit (0); 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) if (opt_manual_link)
{ {
/* Link all given libraries manually. */ /* Link all given libraries manually. */

View File

@ -41,14 +41,17 @@ extern void add_to_cache (const char *path, const char *lib, int flags,
unsigned long int hwcap); unsigned long int hwcap);
/* Declared in readlib.c. */ /* Declared in readlib.c. */
extern int process_file (const char *file_name, const char *lib, int *flag, extern int process_file (const char *real_file_name, const char *file_name,
char **soname, int is_link); const char *lib, int *flag, char **soname,
int is_link);
/* Declared in readelflib.c. */ /* Declared in readelflib.c. */
extern int process_elf_file (const char *file_name, const char *lib, int *flag, extern int process_elf_file (const char *file_name, const char *lib, int *flag,
char **soname, void *file_contents, char **soname, void *file_contents,
size_t file_length); size_t file_length);
/* Declared in chroot_canon.c. */
extern char *chroot_canon (const char *chroot, const char *name);
/* Declared in ldconfig.c. */ /* Declared in ldconfig.c. */
extern int opt_verbose; extern int opt_verbose;

View File

@ -68,11 +68,11 @@ static struct known_names known_libs [] =
/* Returns 0 if everything is ok, != 0 in case of error. */ /* Returns 0 if everything is ok, != 0 in case of error. */
int int
process_file (const char *file_name, const char *lib, int *flag, process_file (const char *real_file_name, const char *file_name,
char **soname, int is_link) const char *lib, int *flag, char **soname, int is_link)
{ {
FILE *file; FILE *file;
struct stat statbuf; struct stat64 statbuf;
void *file_contents; void *file_contents;
int ret; int ret;
@ -83,7 +83,7 @@ process_file (const char *file_name, const char *lib, int *flag,
*flag = FLAG_ANY; *flag = FLAG_ANY;
*soname = NULL; *soname = NULL;
file = fopen (file_name, "rb"); file = fopen (real_file_name, "rb");
if (file == NULL) if (file == NULL)
{ {
/* No error for stale symlink. */ /* No error for stale symlink. */
@ -93,7 +93,7 @@ process_file (const char *file_name, const char *lib, int *flag,
return 1; return 1;
} }
if (fstat (fileno (file), &statbuf) < 0) if (fstat64 (fileno (file), &statbuf) < 0)
{ {
error (0, 0, _("Cannot fstat file %s.\n"), file_name); error (0, 0, _("Cannot fstat file %s.\n"), file_name);
fclose (file); fclose (file);

View 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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 /* 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 C99 is out hopefully all maintained compilers will soon provide the data
types `float complex' and `double complex'. */ 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__ # define _Complex __complex__
#endif #endif