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
 | 
					# default parameters
 | 
				
			||||||
prefix="/usr/local"
 | 
					prefix="/usr/local"
 | 
				
			||||||
 | 
					interp_prefix="/usr/gnemul/qemu-i386"
 | 
				
			||||||
cross_prefix=""
 | 
					cross_prefix=""
 | 
				
			||||||
cc="gcc"
 | 
					cc="gcc"
 | 
				
			||||||
host_cc="gcc"
 | 
					host_cc="gcc"
 | 
				
			||||||
| 
						 | 
					@ -89,6 +90,8 @@ for opt do
 | 
				
			||||||
  case "$opt" in
 | 
					  case "$opt" in
 | 
				
			||||||
  --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
 | 
					  --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`
 | 
					  --source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
 | 
				
			||||||
  ;;
 | 
					  ;;
 | 
				
			||||||
  --cross-prefix=*) cross_prefix=`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 "Standard options:"
 | 
				
			||||||
echo "  --help                   print this message"
 | 
					echo "  --help                   print this message"
 | 
				
			||||||
echo "  --prefix=PREFIX          install in PREFIX [$prefix]"
 | 
					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 ""
 | 
				
			||||||
echo "Advanced options (experts only):"
 | 
					echo "Advanced options (experts only):"
 | 
				
			||||||
echo "  --source-path=PATH       path of source code [$source_path]"
 | 
					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 "/* Automatically generated by configure - do not modify */" > $TMPH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "prefix=$prefix" >> config.mak
 | 
					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 "MAKE=$make" >> config.mak
 | 
				
			||||||
echo "CC=$cc" >> config.mak
 | 
					echo "CC=$cc" >> config.mak
 | 
				
			||||||
echo "GCC_MAJOR=$gcc_major" >> config.mak
 | 
					echo "GCC_MAJOR=$gcc_major" >> config.mak
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,6 @@ struct linux_binprm {
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
        int e_uid, e_gid;
 | 
					        int e_uid, e_gid;
 | 
				
			||||||
        int argc, envc;
 | 
					        int argc, envc;
 | 
				
			||||||
        char * interp_prefix;   /* prefix for interpreter */
 | 
					 | 
				
			||||||
        char * filename;        /* Name of binary */
 | 
					        char * filename;        /* Name of binary */
 | 
				
			||||||
        unsigned long loader, exec;
 | 
					        unsigned long loader, exec;
 | 
				
			||||||
        int dont_iput;          /* binfmt handler has put inode */
 | 
					        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
 | 
						     * is an a.out format binary
 | 
				
			||||||
	     */
 | 
						     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+
 | 
						    elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
 | 
				
			||||||
                                             strlen(bprm->interp_prefix));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    if (elf_interpreter == NULL) {
 | 
						    if (elf_interpreter == NULL) {
 | 
				
			||||||
		free (elf_phdata);
 | 
							free (elf_phdata);
 | 
				
			||||||
| 
						 | 
					@ -765,12 +763,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    strcpy(elf_interpreter, bprm->interp_prefix);
 | 
					 | 
				
			||||||
	    retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
 | 
						    retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
 | 
				
			||||||
	    if(retval >= 0) {
 | 
						    if(retval >= 0) {
 | 
				
			||||||
		retval = read(bprm->fd, 
 | 
							retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
 | 
				
			||||||
			      elf_interpreter+strlen(bprm->interp_prefix), 
 | 
					 | 
				
			||||||
			      elf_ppnt->p_filesz);
 | 
					 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    if(retval < 0) {
 | 
						    if(retval < 0) {
 | 
				
			||||||
	 	perror("load_elf_binary2");
 | 
						 	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);
 | 
						    printf("Using ELF interpreter %s\n", elf_interpreter);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	    if (retval >= 0) {
 | 
						    if (retval >= 0) {
 | 
				
			||||||
		retval = open(elf_interpreter, O_RDONLY);
 | 
							retval = open(path(elf_interpreter), O_RDONLY);
 | 
				
			||||||
		if(retval >= 0) {
 | 
							if(retval >= 0) {
 | 
				
			||||||
		    interpreter_fd = retval;
 | 
							    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, 
 | 
					int elf_exec(const char * filename, char ** argv, char ** envp, 
 | 
				
			||||||
             const char * filename, char ** argv, char ** envp, 
 | 
					 | 
				
			||||||
             struct target_pt_regs * regs, struct image_info *infop)
 | 
					             struct target_pt_regs * regs, struct image_info *infop)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
        struct linux_binprm bprm;
 | 
					        struct linux_binprm bprm;
 | 
				
			||||||
| 
						 | 
					@ -1080,7 +1074,6 @@ int elf_exec(const char *interp_prefix,
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
	    bprm.fd = retval;
 | 
						    bprm.fd = retval;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
        bprm.interp_prefix = (char *)interp_prefix;
 | 
					 | 
				
			||||||
        bprm.filename = (char *)filename;
 | 
					        bprm.filename = (char *)filename;
 | 
				
			||||||
        bprm.sh_bang = 0;
 | 
					        bprm.sh_bang = 0;
 | 
				
			||||||
        bprm.loader = 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;
 | 
					extern TaskState *first_task_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int elf_exec(const char *interp_prefix, 
 | 
					int elf_exec(const char * filename, char ** argv, char ** envp, 
 | 
				
			||||||
             const char * filename, char ** argv, char ** envp, 
 | 
					 | 
				
			||||||
             struct target_pt_regs * regs, struct image_info *infop);
 | 
					             struct target_pt_regs * regs, struct image_info *infop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void target_set_brk(char *new_brk);
 | 
					void target_set_brk(char *new_brk);
 | 
				
			||||||
| 
						 | 
					@ -75,5 +74,6 @@ void process_pending_signals(void *cpu_env);
 | 
				
			||||||
void signal_init(void);
 | 
					void signal_init(void);
 | 
				
			||||||
int queue_signal(int sig, target_siginfo_t *info);
 | 
					int queue_signal(int sig, target_siginfo_t *info);
 | 
				
			||||||
void save_v86_state(CPUX86State *env);
 | 
					void save_v86_state(CPUX86State *env);
 | 
				
			||||||
 | 
					void init_paths(const char *prefix);
 | 
				
			||||||
 | 
					const char *path(const char *pathname);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue