bonefish+axeld:
The runtime loader did not correctly resolve %A correctly with the actual normalized program path. IOW it would not work correctly with symlinks to applications that had their own lib directory. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23986 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8b3b2b4ff1
commit
12a5e9a4a2
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@ -263,8 +263,21 @@ find_loaded_image_by_id(image_id id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_program_path()
|
||||||
|
{
|
||||||
|
for (image_t *image = sLoadedImages.head; image; image = image->next) {
|
||||||
|
if (image->type == B_APP_IMAGE)
|
||||||
|
return image->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
parse_elf_header(struct Elf32_Ehdr *eheader, int32 *_pheaderSize, int32 *_sheaderSize)
|
parse_elf_header(struct Elf32_Ehdr *eheader, int32 *_pheaderSize,
|
||||||
|
int32 *_sheaderSize)
|
||||||
{
|
{
|
||||||
if (memcmp(eheader->e_ident, ELF_MAGIC, 4) != 0)
|
if (memcmp(eheader->e_ident, ELF_MAGIC, 4) != 0)
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
@ -990,7 +1003,7 @@ load_container(char const *name, image_type type, const char *rpath, image_t **_
|
|||||||
strlcpy(path, name, sizeof(path));
|
strlcpy(path, name, sizeof(path));
|
||||||
|
|
||||||
// Try to load explicit image path first
|
// Try to load explicit image path first
|
||||||
fd = open_executable(path, type, rpath);
|
fd = open_executable(path, type, rpath, get_program_path());
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
FATAL("cannot open file %s\n", path);
|
FATAL("cannot open file %s\n", path);
|
||||||
KTRACE("rld: load_container(\"%s\"): failed to open file", name);
|
KTRACE("rld: load_container(\"%s\"): failed to open file", name);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@ -82,8 +82,8 @@ search_path_for_type(image_type type)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
try_open_executable(const char *dir, int dirLength, const char *name, char *path,
|
try_open_executable(const char *dir, int dirLength, const char *name,
|
||||||
size_t pathLength)
|
const char *programPath, char *path, size_t pathLength)
|
||||||
{
|
{
|
||||||
size_t nameLength = strlen(name);
|
size_t nameLength = strlen(name);
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
@ -93,18 +93,19 @@ try_open_executable(const char *dir, int dirLength, const char *name, char *path
|
|||||||
if (dirLength > 0) {
|
if (dirLength > 0) {
|
||||||
char *buffer = path;
|
char *buffer = path;
|
||||||
|
|
||||||
|
if (programPath == NULL)
|
||||||
|
programPath = gProgramArgs->program_path;
|
||||||
|
|
||||||
if (dirLength >= 2 && strncmp(dir, "%A", 2) == 0) {
|
if (dirLength >= 2 && strncmp(dir, "%A", 2) == 0) {
|
||||||
// Replace %A with current app folder path (of course,
|
// Replace %A with current app folder path (of course,
|
||||||
// this must be the first part of the path)
|
// this must be the first part of the path)
|
||||||
// ToDo: Maybe using first image info is better suited than
|
char *lastSlash = strrchr(programPath, '/');
|
||||||
// gProgamArgs->program_path here?
|
|
||||||
char *lastSlash = strrchr(gProgramArgs->program_path, '/');
|
|
||||||
int bytesCopied;
|
int bytesCopied;
|
||||||
|
|
||||||
// copy what's left (when the application name is removed)
|
// copy what's left (when the application name is removed)
|
||||||
if (lastSlash != NULL) {
|
if (lastSlash != NULL) {
|
||||||
strlcpy(buffer, gProgramArgs->program_path,
|
strlcpy(buffer, programPath,
|
||||||
min((int)pathLength, lastSlash + 1 - gProgramArgs->program_path));
|
min((int)pathLength, lastSlash + 1 - programPath));
|
||||||
} else
|
} else
|
||||||
strlcpy(buffer, ".", pathLength);
|
strlcpy(buffer, ".", pathLength);
|
||||||
|
|
||||||
@ -160,7 +161,8 @@ try_open_executable(const char *dir, int dirLength, const char *name, char *path
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
search_executable_in_path_list(const char *name, const char *pathList,
|
search_executable_in_path_list(const char *name, const char *pathList,
|
||||||
int pathListLen, char *pathBuffer, size_t pathBufferLength)
|
int pathListLen, const char *programPath, char *pathBuffer,
|
||||||
|
size_t pathBufferLength)
|
||||||
{
|
{
|
||||||
const char *pathListEnd = pathList + pathListLen;
|
const char *pathListEnd = pathList + pathListLen;
|
||||||
status_t status = B_ENTRY_NOT_FOUND;
|
status_t status = B_ENTRY_NOT_FOUND;
|
||||||
@ -176,8 +178,8 @@ search_executable_in_path_list(const char *name, const char *pathList,
|
|||||||
while (pathEnd < pathListEnd && *pathEnd != ':')
|
while (pathEnd < pathListEnd && *pathEnd != ':')
|
||||||
pathEnd++;
|
pathEnd++;
|
||||||
|
|
||||||
fd = try_open_executable(pathList, pathEnd - pathList, name, pathBuffer,
|
fd = try_open_executable(pathList, pathEnd - pathList, name,
|
||||||
pathBufferLength);
|
programPath, pathBuffer, pathBufferLength);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
// see if it's a dir
|
// see if it's a dir
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
@ -199,7 +201,8 @@ search_executable_in_path_list(const char *name, const char *pathList,
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
open_executable(char *name, image_type type, const char *rpath)
|
open_executable(char *name, image_type type, const char *rpath,
|
||||||
|
const char *programPath)
|
||||||
{
|
{
|
||||||
const char *paths;
|
const char *paths;
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
@ -214,7 +217,7 @@ open_executable(char *name, image_type type, const char *rpath)
|
|||||||
// Even though ELF specs don't say this, we give shared libraries
|
// Even though ELF specs don't say this, we give shared libraries
|
||||||
// another chance and look them up in the usual search paths - at
|
// another chance and look them up in the usual search paths - at
|
||||||
// least that seems to be what BeOS does, and since it doesn't hurt...
|
// least that seems to be what BeOS does, and since it doesn't hurt...
|
||||||
paths = strrchr(name, '/');
|
paths = strrchr(name, '/') + 1;
|
||||||
memmove(name, paths, strlen(paths) + 1);
|
memmove(name, paths, strlen(paths) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,11 +232,11 @@ open_executable(char *name, image_type type, const char *rpath)
|
|||||||
// If there is no ';', we set only secondList to simplify things.
|
// If there is no ';', we set only secondList to simplify things.
|
||||||
if (firstList) {
|
if (firstList) {
|
||||||
fd = search_executable_in_path_list(name, firstList,
|
fd = search_executable_in_path_list(name, firstList,
|
||||||
semicolon - firstList, buffer, sizeof(buffer));
|
semicolon - firstList, programPath, buffer, sizeof(buffer));
|
||||||
}
|
}
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fd = search_executable_in_path_list(name, secondList,
|
fd = search_executable_in_path_list(name, secondList,
|
||||||
strlen(secondList), buffer, sizeof(buffer));
|
strlen(secondList), programPath, buffer, sizeof(buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,13 +245,13 @@ open_executable(char *name, image_type type, const char *rpath)
|
|||||||
paths = search_path_for_type(type);
|
paths = search_path_for_type(type);
|
||||||
if (paths) {
|
if (paths) {
|
||||||
fd = search_executable_in_path_list(name, paths, strlen(paths),
|
fd = search_executable_in_path_list(name, paths, strlen(paths),
|
||||||
buffer, sizeof(buffer));
|
programPath, buffer, sizeof(buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
// we found it, copy path!
|
// we found it, copy path!
|
||||||
TRACE(("runtime_loader: open_container(%s): found at %s\n", name, buffer));
|
TRACE(("runtime_loader: open_executable(%s): found at %s\n", name, buffer));
|
||||||
strlcpy(name, buffer, PATH_MAX);
|
strlcpy(name, buffer, PATH_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +281,7 @@ test_executable(const char *name, uid_t user, gid_t group, char *invoker)
|
|||||||
|
|
||||||
strlcpy(path, name, sizeof(path));
|
strlcpy(path, name, sizeof(path));
|
||||||
|
|
||||||
fd = open_executable(path, B_APP_IMAGE, NULL);
|
fd = open_executable(path, B_APP_IMAGE, NULL, NULL);
|
||||||
if (fd < B_OK)
|
if (fd < B_OK)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@ -23,7 +23,8 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int runtime_loader(void *arg);
|
int runtime_loader(void *arg);
|
||||||
int open_executable(char *name, image_type type, const char *rpath);
|
int open_executable(char *name, image_type type, const char *rpath,
|
||||||
|
const char *programPath);
|
||||||
status_t test_executable(const char *path, uid_t user, gid_t group,
|
status_t test_executable(const char *path, uid_t user, gid_t group,
|
||||||
char *starter);
|
char *starter);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user