path patch
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@96 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
ec86b0fb3a
commit
32ce63371a
|
@ -19,6 +19,7 @@ TMPH="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.h"
|
|||
|
||||
# default parameters
|
||||
prefix="/usr/local"
|
||||
interp_prefix="/usr/gnemul/qemu-i386"
|
||||
cross_prefix=""
|
||||
cc="gcc"
|
||||
host_cc="gcc"
|
||||
|
@ -89,6 +90,8 @@ for opt do
|
|||
case "$opt" in
|
||||
--prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
|
||||
;;
|
||||
--interp-prefix=*) interp_prefix=`echo $opt | cut -d '=' -f 2`
|
||||
;;
|
||||
--source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
|
||||
;;
|
||||
--cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
|
||||
|
@ -172,7 +175,7 @@ EOF
|
|||
echo "Standard options:"
|
||||
echo " --help print this message"
|
||||
echo " --prefix=PREFIX install in PREFIX [$prefix]"
|
||||
echo " for audio/video/image support"
|
||||
echo " --interp-prefix=PREFIX where to find shared libraries, etc. [$interp_prefix]"
|
||||
echo ""
|
||||
echo "Advanced options (experts only):"
|
||||
echo " --source-path=PATH path of source code [$source_path]"
|
||||
|
@ -198,7 +201,7 @@ echo "# Automatically generated by configure - do not modify" > config.mak
|
|||
echo "/* Automatically generated by configure - do not modify */" > $TMPH
|
||||
|
||||
echo "prefix=$prefix" >> config.mak
|
||||
echo "#define CONFIG_QEMU_PREFIX \"$prefix\"" >> $TMPH
|
||||
echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix\"" >> $TMPH
|
||||
echo "MAKE=$make" >> config.mak
|
||||
echo "CC=$cc" >> config.mak
|
||||
echo "GCC_MAJOR=$gcc_major" >> config.mak
|
||||
|
|
|
@ -70,7 +70,6 @@ struct linux_binprm {
|
|||
int fd;
|
||||
int e_uid, e_gid;
|
||||
int argc, envc;
|
||||
char * interp_prefix; /* prefix for interpreter */
|
||||
char * filename; /* Name of binary */
|
||||
unsigned long loader, exec;
|
||||
int dont_iput; /* binfmt handler has put inode */
|
||||
|
@ -756,8 +755,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
|
|||
* is an a.out format binary
|
||||
*/
|
||||
|
||||
elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+
|
||||
strlen(bprm->interp_prefix));
|
||||
elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
|
||||
|
||||
if (elf_interpreter == NULL) {
|
||||
free (elf_phdata);
|
||||
|
@ -765,12 +763,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
strcpy(elf_interpreter, bprm->interp_prefix);
|
||||
retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
|
||||
if(retval >= 0) {
|
||||
retval = read(bprm->fd,
|
||||
elf_interpreter+strlen(bprm->interp_prefix),
|
||||
elf_ppnt->p_filesz);
|
||||
retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
|
||||
}
|
||||
if(retval < 0) {
|
||||
perror("load_elf_binary2");
|
||||
|
@ -792,7 +787,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
|
|||
printf("Using ELF interpreter %s\n", elf_interpreter);
|
||||
#endif
|
||||
if (retval >= 0) {
|
||||
retval = open(elf_interpreter, O_RDONLY);
|
||||
retval = open(path(elf_interpreter), O_RDONLY);
|
||||
if(retval >= 0) {
|
||||
interpreter_fd = retval;
|
||||
}
|
||||
|
@ -1060,8 +1055,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
|
|||
|
||||
|
||||
|
||||
int elf_exec(const char *interp_prefix,
|
||||
const char * filename, char ** argv, char ** envp,
|
||||
int elf_exec(const char * filename, char ** argv, char ** envp,
|
||||
struct target_pt_regs * regs, struct image_info *infop)
|
||||
{
|
||||
struct linux_binprm bprm;
|
||||
|
@ -1080,7 +1074,6 @@ int elf_exec(const char *interp_prefix,
|
|||
else {
|
||||
bprm.fd = retval;
|
||||
}
|
||||
bprm.interp_prefix = (char *)interp_prefix;
|
||||
bprm.filename = (char *)filename;
|
||||
bprm.sh_bang = 0;
|
||||
bprm.loader = 0;
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/* Code to mangle pathnames into those matching a given prefix.
|
||||
eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so");
|
||||
|
||||
The assumption is that this area does not change.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include "qemu.h"
|
||||
|
||||
struct pathelem
|
||||
{
|
||||
/* Name of this, eg. lib */
|
||||
char *name;
|
||||
/* Full path name, eg. /usr/gnemul/x86-linux/lib. */
|
||||
char *pathname;
|
||||
struct pathelem *parent;
|
||||
/* Children */
|
||||
unsigned int num_entries;
|
||||
struct pathelem *entries[0];
|
||||
};
|
||||
|
||||
static struct pathelem *base;
|
||||
|
||||
/* First N chars of S1 match S2, and S2 is N chars long. */
|
||||
static int strneq(const char *s1, unsigned int n, const char *s2)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (s1[i] != s2[i])
|
||||
return 0;
|
||||
return s2[i] == 0;
|
||||
}
|
||||
|
||||
static struct pathelem *add_entry(struct pathelem *root, const char *name);
|
||||
|
||||
static struct pathelem *new_entry(const char *root,
|
||||
struct pathelem *parent,
|
||||
const char *name)
|
||||
{
|
||||
struct pathelem *new = malloc(sizeof(*new));
|
||||
new->name = strdup(name);
|
||||
asprintf(&new->pathname, "%s/%s", root, name);
|
||||
new->num_entries = 0;
|
||||
return new;
|
||||
}
|
||||
|
||||
#define streq(a,b) (strcmp((a), (b)) == 0)
|
||||
|
||||
static struct pathelem *add_dir_maybe(struct pathelem *path)
|
||||
{
|
||||
DIR *dir;
|
||||
|
||||
if ((dir = opendir(path->pathname)) != NULL) {
|
||||
struct dirent *dirent;
|
||||
|
||||
while ((dirent = readdir(dir)) != NULL) {
|
||||
if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
|
||||
path = add_entry(path, dirent->d_name);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
static struct pathelem *add_entry(struct pathelem *root, const char *name)
|
||||
{
|
||||
root->num_entries++;
|
||||
|
||||
root = realloc(root, sizeof(*root)
|
||||
+ sizeof(root->entries[0])*root->num_entries);
|
||||
|
||||
root->entries[root->num_entries-1] = new_entry(root->pathname, root, name);
|
||||
root->entries[root->num_entries-1]
|
||||
= add_dir_maybe(root->entries[root->num_entries-1]);
|
||||
return root;
|
||||
}
|
||||
|
||||
/* This needs to be done after tree is stabalized (ie. no more reallocs!). */
|
||||
static void set_parents(struct pathelem *child, struct pathelem *parent)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
child->parent = parent;
|
||||
for (i = 0; i < child->num_entries; i++)
|
||||
set_parents(child->entries[i], child);
|
||||
}
|
||||
|
||||
void init_paths(const char *prefix)
|
||||
{
|
||||
if (prefix[0] != '/' ||
|
||||
prefix[0] == '\0' ||
|
||||
!strcmp(prefix, "/"))
|
||||
return;
|
||||
|
||||
base = new_entry("", NULL, prefix+1);
|
||||
base = add_dir_maybe(base);
|
||||
set_parents(base, base);
|
||||
}
|
||||
|
||||
/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
|
||||
static const char *
|
||||
follow_path(const struct pathelem *cursor, const char *name)
|
||||
{
|
||||
unsigned int i, namelen;
|
||||
|
||||
name += strspn(name, "/");
|
||||
namelen = strcspn(name, "/");
|
||||
|
||||
if (namelen == 0)
|
||||
return cursor->pathname;
|
||||
|
||||
if (strneq(name, namelen, ".."))
|
||||
return follow_path(cursor->parent, name + namelen);
|
||||
|
||||
if (strneq(name, namelen, "."))
|
||||
return follow_path(cursor, name + namelen);
|
||||
|
||||
for (i = 0; i < cursor->num_entries; i++)
|
||||
if (strneq(name, namelen, cursor->entries[i]->name))
|
||||
return follow_path(cursor->entries[i], name + namelen);
|
||||
|
||||
/* Not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look for path in emulation dir, otherwise return name. */
|
||||
const char *path(const char *name)
|
||||
{
|
||||
/* Only do absolute paths: quick and dirty, but should mostly be OK.
|
||||
Could do relative by tracking cwd. */
|
||||
if (!base || name[0] != '/')
|
||||
return name;
|
||||
|
||||
return follow_path(base, name) ?: name;
|
||||
}
|
|
@ -60,8 +60,7 @@ typedef struct TaskState {
|
|||
|
||||
extern TaskState *first_task_state;
|
||||
|
||||
int elf_exec(const char *interp_prefix,
|
||||
const char * filename, char ** argv, char ** envp,
|
||||
int elf_exec(const char * filename, char ** argv, char ** envp,
|
||||
struct target_pt_regs * regs, struct image_info *infop);
|
||||
|
||||
void target_set_brk(char *new_brk);
|
||||
|
@ -75,5 +74,6 @@ void process_pending_signals(void *cpu_env);
|
|||
void signal_init(void);
|
||||
int queue_signal(int sig, target_siginfo_t *info);
|
||||
void save_v86_state(CPUX86State *env);
|
||||
|
||||
void init_paths(const char *prefix);
|
||||
const char *path(const char *pathname);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue