mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Update.
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:
42
ChangeLog
42
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>
|
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.
|
||||||
|
2
Makefile
2
Makefile
@ -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))
|
||||||
|
@ -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
|
||||||
|
@ -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
172
elf/chroot_canon.c
Normal 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;
|
||||||
|
}
|
250
elf/ldconfig.c
250
elf/ldconfig.c
@ -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. */
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user