⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 path.c

📁 qemu虚拟机代码
💻 C
字号:
/* 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);    if (base->num_entries == 0) {        free (base);        base = NULL;    } else {        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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -