(dl_main): First check existence of ld.so.preload with access.

This commit is contained in:
Ulrich Drepper 2004-09-02 02:52:26 +00:00
parent 6698501fda
commit 761490a1d7

View File

@ -1138,103 +1138,114 @@ of this helper program; chances are you did not intend to run this program.\n\
HP_TIMING_ACCUM_NT (load_time, diff); HP_TIMING_ACCUM_NT (load_time, diff);
} }
/* Read the contents of the file. */ /* There usually is no ld.so.preload file, it should only be used
const char preload_file[] = "/etc/ld.so.preload"; for emergencies and testing. So the open call etc should usually
file = _dl_sysdep_read_whole_file (preload_file, &file_size, fail. Using access() on a non-existing file is faster than using
PROT_READ | PROT_WRITE); open(). So we do this first. If it succeeds we do almost twice
if (__builtin_expect (file != MAP_FAILED, 0)) the work but this does not matter, since it is not for production
use. */
static const char preload_file[] = "/etc/ld.so.preload";
if (__builtin_expect (__access (preload_file, R_OK) == 0, 0))
{ {
/* Parse the file. It contains names of libraries to be loaded, /* Read the contents of the file. */
separated by white spaces or `:'. It may also contain file = _dl_sysdep_read_whole_file (preload_file, &file_size,
comments introduced by `#'. */ PROT_READ | PROT_WRITE);
char *problem; if (__builtin_expect (file != MAP_FAILED, 0))
char *runp;
size_t rest;
/* Eliminate comments. */
runp = file;
rest = file_size;
while (rest > 0)
{ {
char *comment = memchr (runp, '#', rest); /* Parse the file. It contains names of libraries to be loaded,
if (comment == NULL) separated by white spaces or `:'. It may also contain
break; comments introduced by `#'. */
char *problem;
char *runp;
size_t rest;
rest -= comment - runp; /* Eliminate comments. */
do
*comment = ' ';
while (--rest > 0 && *++comment != '\n');
}
/* We have one problematic case: if we have a name at the end of
the file without a trailing terminating characters, we cannot
place the \0. Handle the case separately. */
if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
&& file[file_size - 1] != '\n' && file[file_size - 1] != ':')
{
problem = &file[file_size];
while (problem > file && problem[-1] != ' ' && problem[-1] != '\t'
&& problem[-1] != '\n' && problem[-1] != ':')
--problem;
if (problem > file)
problem[-1] = '\0';
}
else
{
problem = NULL;
file[file_size - 1] = '\0';
}
HP_TIMING_NOW (start);
if (file != problem)
{
char *p;
runp = file; runp = file;
while ((p = strsep (&runp, ": \t\n")) != NULL) rest = file_size;
if (p[0] != '\0') while (rest > 0)
{ {
const char *objname; char *comment = memchr (runp, '#', rest);
const char *err_str = NULL; if (comment == NULL)
struct map_args args; break;
args.str = p; rest -= comment - runp;
args.loader = GL(dl_loaded); do
args.is_preloaded = 1; *comment = ' ';
args.mode = 0; while (--rest > 0 && *++comment != '\n');
}
(void) _dl_catch_error (&objname, &err_str, map_doit, &args); /* We have one problematic case: if we have a name at the end of
if (__builtin_expect (err_str != NULL, 0)) the file without a trailing terminating characters, we cannot
place the \0. Handle the case separately. */
if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
&& file[file_size - 1] != '\n' && file[file_size - 1] != ':')
{
problem = &file[file_size];
while (problem > file && problem[-1] != ' '
&& problem[-1] != '\t'
&& problem[-1] != '\n' && problem[-1] != ':')
--problem;
if (problem > file)
problem[-1] = '\0';
}
else
{
problem = NULL;
file[file_size - 1] = '\0';
}
HP_TIMING_NOW (start);
if (file != problem)
{
char *p;
runp = file;
while ((p = strsep (&runp, ": \t\n")) != NULL)
if (p[0] != '\0')
{ {
_dl_error_printf ("\ const char *objname;
const char *err_str = NULL;
struct map_args args;
args.str = p;
args.loader = GL(dl_loaded);
args.is_preloaded = 1;
args.mode = 0;
(void) _dl_catch_error (&objname, &err_str, map_doit,
&args);
if (__builtin_expect (err_str != NULL, 0))
{
_dl_error_printf ("\
ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n", ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
p, preload_file); p, preload_file);
/* No need to call free, this is still before the libc's /* No need to call free, this is still before
malloc is used. */ the libc's malloc is used. */
}
else if (++args.map->l_opencount == 1)
/* It is no duplicate. */
++npreloads;
} }
else if (++args.map->l_opencount == 1) }
/* It is no duplicate. */
++npreloads; if (problem != NULL)
} {
char *p = strndupa (problem, file_size - (problem - file));
struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1,
lt_library, 0, 0);
if (++new_map->l_opencount == 1)
/* It is no duplicate. */
++npreloads;
}
HP_TIMING_NOW (stop);
HP_TIMING_DIFF (diff, start, stop);
HP_TIMING_ACCUM_NT (load_time, diff);
/* We don't need the file anymore. */
__munmap (file, file_size);
} }
if (problem != NULL)
{
char *p = strndupa (problem, file_size - (problem - file));
struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1,
lt_library, 0, 0);
if (++new_map->l_opencount == 1)
/* It is no duplicate. */
++npreloads;
}
HP_TIMING_NOW (stop);
HP_TIMING_DIFF (diff, start, stop);
HP_TIMING_ACCUM_NT (load_time, diff);
/* We don't need the file anymore. */
__munmap (file, file_size);
} }
if (__builtin_expect (npreloads, 0) != 0) if (__builtin_expect (npreloads, 0) != 0)