The search path feature now works properly. The path found is now propagated
back to load_container() so that map_image() has the chance to succeed. The FATAL() macro now uses dprintf() instead of printf() when TRACE_RLD is defined. Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9218 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+105
-93
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
|
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
** Distributed under the terms of the OpenBeOS License.
|
** Distributed under the terms of the Haiku License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
** Distributed under the terms of the NewOS License.
|
** Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// ToDo: this should not really be build with the kernel build rules...
|
||||||
#ifdef _KERNEL_MODE
|
#ifdef _KERNEL_MODE
|
||||||
# undef _KERNEL_MODE
|
# undef _KERNEL_MODE
|
||||||
#endif
|
#endif
|
||||||
@@ -27,7 +28,8 @@
|
|||||||
|
|
||||||
#include "rld_priv.h"
|
#include "rld_priv.h"
|
||||||
|
|
||||||
#define TRACE_RLD
|
|
||||||
|
//#define TRACE_RLD
|
||||||
#ifdef TRACE_RLD
|
#ifdef TRACE_RLD
|
||||||
# define TRACE(x) dprintf x
|
# define TRACE(x) dprintf x
|
||||||
#else
|
#else
|
||||||
@@ -140,17 +142,14 @@ static struct uspace_program_args const *gProgramArgs;
|
|||||||
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
|
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
|
||||||
|
|
||||||
|
|
||||||
/*
|
#ifdef TRACE_RLD
|
||||||
* This macro is non ISO compliant, but a gcc extension
|
|
||||||
*/
|
|
||||||
#define FATAL(x,y...) \
|
#define FATAL(x,y...) \
|
||||||
if (x) { \
|
if (x) { \
|
||||||
printf("rld.so: " y); \
|
dprintf("rld.so: " y); \
|
||||||
_kern_exit(0); \
|
_kern_exit(0); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TRACE_RLD
|
|
||||||
void
|
void
|
||||||
dprintf(const char *format, ...)
|
dprintf(const char *format, ...)
|
||||||
{
|
{
|
||||||
@@ -164,6 +163,14 @@ dprintf(const char *format, ...)
|
|||||||
|
|
||||||
va_end(list);
|
va_end(list);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define FATAL(x,y...) \
|
||||||
|
if (x) { \
|
||||||
|
printf("rld.so: " y); \
|
||||||
|
_kern_exit(0); \
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -818,74 +825,115 @@ register_image(image_t *image, int fd, const char *path)
|
|||||||
image->id = _kern_register_image(&info, sizeof(image_info));
|
image->id = _kern_register_image(&info, sizeof(image_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
search_container(char const *name, const char *paths)
|
static const char *
|
||||||
|
search_path_for_type(image_type type)
|
||||||
{
|
{
|
||||||
char *leaf_name;
|
switch (type) {
|
||||||
char search_paths[PATH_MAX + 1];
|
#if 0
|
||||||
|
// ToDo: note, the getenv() call is not yet part of rld.so
|
||||||
|
case B_APP_IMAGE:
|
||||||
|
return getenv("PATH");
|
||||||
|
case B_LIBRARY_IMAGE:
|
||||||
|
return getenv("LIBRARY_PATH");
|
||||||
|
case B_ADD_ON_IMAGE:
|
||||||
|
return getenv("ADDON_PATH");
|
||||||
|
#else
|
||||||
|
case B_APP_IMAGE:
|
||||||
|
return "/boot/home/config/bin:"
|
||||||
|
"/boot/apps:"
|
||||||
|
"/boot/preferences:"
|
||||||
|
"/boot/beos/apps:"
|
||||||
|
"/boot/beos/preferences:"
|
||||||
|
"/boot/develop/tools/gnupro/bin";
|
||||||
|
|
||||||
|
case B_LIBRARY_IMAGE:
|
||||||
|
return "%A/lib:/boot/home/config/lib:/boot/beos/system/lib";
|
||||||
|
|
||||||
|
case B_ADD_ON_IMAGE:
|
||||||
|
return "%A/lib:/boot/home/config/lib:/boot/beos/system/lib";
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
open_container(char *name, image_type type)
|
||||||
|
{
|
||||||
|
char searchPath[PATH_MAX];
|
||||||
|
const char *paths;
|
||||||
char *path;
|
char *path;
|
||||||
char *next_path_token = NULL;
|
char *nextPathToken = NULL;
|
||||||
char buffer[PATH_MAX + 1];
|
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
if (!name || !paths)
|
if (strchr(name, '/')) {
|
||||||
return B_ERROR;
|
// the name already contains a path, we don't have to search for it
|
||||||
|
return _kern_open(-1, name, O_RDONLY);
|
||||||
|
}
|
||||||
|
|
||||||
leaf_name = strrchr(name, '/');
|
// let's evaluate the system path variables to find the container
|
||||||
if (leaf_name != NULL)
|
|
||||||
leaf_name++;
|
paths = search_path_for_type(type);
|
||||||
else
|
if (paths == NULL)
|
||||||
leaf_name = (char *) name;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
// duplicate environment variable before screw it!
|
// duplicate environment variable before screw it!
|
||||||
strncpy(search_paths, paths, PATH_MAX);
|
strlcpy(searchPath, paths, PATH_MAX);
|
||||||
|
|
||||||
dprintf("rld.so: search_container(%s (%s), %s)\n", name, leaf_name, paths);
|
TRACE(("rld.so: open_container() %s in %s\n", name, searchPath));
|
||||||
|
|
||||||
// TODO: when available, switch to thread-aware strtok_r() version
|
path = strtok_r(searchPath, ":", &nextPathToken);
|
||||||
path = strtok_r(search_paths, ":", &next_path_token);
|
while (path != NULL) {
|
||||||
while (path) {
|
char buffer[PATH_MAX + 1];
|
||||||
if (strncmp(path, "%A/", 3) == 0) {
|
int fd;
|
||||||
// Replace %A with current app folder path
|
|
||||||
// Maybe using first image info is better suited than gProgamArgs->program_path here...
|
if (strncmp(path, "%A", 2) == 0) {
|
||||||
char *end_slash;
|
// Replace %A with current app folder path (of course,
|
||||||
end_slash = strrchr(gProgramArgs->program_path, '/');
|
// this must be the first part of the path)
|
||||||
if (end_slash != NULL) {
|
// ToDo: Maybe using first image info is better suited than gProgamArgs->program_path here?
|
||||||
strncpy(buffer, gProgramArgs->program_path, PATH_MAX);
|
char *lastSlash = strrchr(gProgramArgs->program_path, '/');
|
||||||
strncat(end_slash, path + 2, PATH_MAX);
|
|
||||||
} else {
|
// copy what's left (when the application name is removed)
|
||||||
// FIXME: does _kern_open() resolve relative path?
|
if (lastSlash != NULL) {
|
||||||
// If not, call getcwd() instead here...
|
strlcpy(buffer, gProgramArgs->program_path,
|
||||||
strncpy(buffer, ".", PATH_MAX);
|
min(PATH_MAX, lastSlash + 1 - gProgramArgs->program_path));
|
||||||
strncat(buffer, path + 2, PATH_MAX);
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
// Take the path AS-IS
|
strlcpy(buffer, ".", PATH_MAX);
|
||||||
// TODO: remove any lasting / in path
|
|
||||||
strncpy(buffer, path, PATH_MAX);
|
|
||||||
|
|
||||||
strncat(buffer, "/", PATH_MAX);
|
strlcat(buffer, path + 2, PATH_MAX);
|
||||||
strncat(buffer, leaf_name, PATH_MAX);
|
} else {
|
||||||
|
// Take the path as-is
|
||||||
|
strlcpy(buffer, path, PATH_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
dprintf("rld.so: search_container(%s): trying %s\n", leaf_name, buffer);
|
strlcat(buffer, "/", PATH_MAX);
|
||||||
|
// Several slashes in sequence will be ignored, so we're playing safe and add one more
|
||||||
|
strlcat(buffer, name, PATH_MAX);
|
||||||
|
|
||||||
fd = _kern_open(-1, buffer, 0);
|
TRACE(("rld.so: open_container(%s): trying %s\n", name, buffer));
|
||||||
if (fd >= 0) {
|
|
||||||
dprintf("rld.so: search_container(%s): found at %s\n", leaf_name, buffer);
|
fd = _kern_open(-1, buffer, O_RDONLY);
|
||||||
break; // Found!
|
if (fd >= B_OK) {
|
||||||
|
// we found it, copy path!
|
||||||
|
TRACE(("rld.so: open_container(%s): found at %s\n", name, buffer));
|
||||||
|
strlcpy(name, buffer, PATH_MAX);
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try next search path
|
// Try next search path
|
||||||
path = strtok_r(NULL, ":", &next_path_token);
|
path = strtok_r(NULL, ":", &nextPathToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (fd < 0) ? B_NAME_NOT_FOUND : fd;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static image_t *
|
static image_t *
|
||||||
load_container(char const *path, char const *name, image_type type)
|
load_container(char const *containerPath, char const *name, image_type type)
|
||||||
{
|
{
|
||||||
int32 pheaderSize, sheaderSize;
|
int32 pheaderSize, sheaderSize;
|
||||||
|
char path[PATH_MAX];
|
||||||
int fd;
|
int fd;
|
||||||
int len;
|
int len;
|
||||||
char ph_buff[4096];
|
char ph_buff[4096];
|
||||||
@@ -904,42 +952,10 @@ load_container(char const *path, char const *name, image_type type)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strlcpy(path, containerPath, sizeof(path));
|
||||||
|
|
||||||
// Try to load explicit image path first
|
// Try to load explicit image path first
|
||||||
fd = _kern_open(-1, path, 0);
|
fd = open_container(path, type);
|
||||||
if (fd < 0) {
|
|
||||||
const char *paths;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
#if 0
|
|
||||||
case B_APP_IMAGE: paths = getenv("PATH"); break;
|
|
||||||
case B_LIBRARY_IMAGE: paths = getenv("LIBRARY_PATH"); break;
|
|
||||||
case B_ADD_ON_IMAGE: paths = getenv("ADDON_PATH"); break;
|
|
||||||
#else
|
|
||||||
case B_APP_IMAGE:
|
|
||||||
paths = "/boot/home/config/bin:"
|
|
||||||
"/boot/apps:"
|
|
||||||
"/boot/preferences:"
|
|
||||||
"/boot/beos/apps:"
|
|
||||||
"/boot/beos/preferences:"
|
|
||||||
"/boot/develop/tools/gnupro/bin";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_LIBRARY_IMAGE:
|
|
||||||
paths = "%A/lib:/boot/home/config/lib:/boot/beos/system/lib";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_ADD_ON_IMAGE:
|
|
||||||
paths = "%A/lib:/boot/home/config/lib:/boot/beos/system/lib";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
paths = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paths)
|
|
||||||
// search container in these paths
|
|
||||||
fd = search_container(name, paths);
|
|
||||||
}
|
|
||||||
FATAL((fd < 0), "cannot open file %s\n", path);
|
FATAL((fd < 0), "cannot open file %s\n", path);
|
||||||
|
|
||||||
len = _kern_read(fd, 0, &eheader, sizeof(eheader));
|
len = _kern_read(fd, 0, &eheader, sizeof(eheader));
|
||||||
@@ -986,7 +1002,6 @@ load_dependencies(image_t *image)
|
|||||||
{
|
{
|
||||||
struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr;
|
struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr;
|
||||||
addr_t needed_offset;
|
addr_t needed_offset;
|
||||||
// char path[256];
|
|
||||||
uint32 i, j;
|
uint32 i, j;
|
||||||
|
|
||||||
if (!d)
|
if (!d)
|
||||||
@@ -1000,9 +1015,6 @@ load_dependencies(image_t *image)
|
|||||||
switch (d[i].d_tag) {
|
switch (d[i].d_tag) {
|
||||||
case DT_NEEDED:
|
case DT_NEEDED:
|
||||||
needed_offset = d[i].d_un.d_ptr;
|
needed_offset = d[i].d_un.d_ptr;
|
||||||
// ToDo: ever heard of the LIBRARY_PATH env variable?
|
|
||||||
// sprintf(path, "/boot/beos/system/lib/%s", STRING(image, needed_offset));
|
|
||||||
// image->needed[j] = load_container(path, STRING(image, needed_offset), B_LIBRARY_IMAGE);
|
|
||||||
image->needed[j] = load_container(STRING(image, needed_offset),
|
image->needed[j] = load_container(STRING(image, needed_offset),
|
||||||
STRING(image, needed_offset), B_LIBRARY_IMAGE);
|
STRING(image, needed_offset), B_LIBRARY_IMAGE);
|
||||||
j += 1;
|
j += 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user