From: "Kirill A. Shutemov" <k.shutemov@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] [REPOST] Simplily linux-user/path.c
Date: Mon, 19 Feb 2007 16:04:09 +0300 [thread overview]
Message-ID: <20070219130409.GD25556@localhost.localdomain> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 62 bytes --]
Fixed version of the patch in the attacment. Please, comment.
[-- Attachment #1.2: qemu-0.8.2-alt-path.patch --]
[-- Type: text/plain, Size: 4519 bytes --]
--- qemu-0.8.2/linux-user/path.c.orig 2006-12-21 17:16:03 +0200
+++ qemu-0.8.2/linux-user/path.c 2006-12-21 17:14:08 +0200
@@ -1,147 +1,37 @@
/* 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 <sys/stat.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);
-}
+static char* pref;
void init_paths(const char *prefix)
{
if (prefix[0] != '/' ||
- prefix[0] == '\0' ||
- !strcmp(prefix, "/"))
+ 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;
+ pref = strdup(prefix);
}
/* Look for path in emulation dir, otherwise return name. */
const char *path(const char *name)
{
+ char *newname = (char *) alloca(strlen(pref)+strlen(name)+1);
+ struct stat buf;
/* Only do absolute paths: quick and dirty, but should mostly be OK.
Could do relative by tracking cwd. */
- if (!base || name[0] != '/')
- return name;
+ if (!pref || name[0] != '/')
+ return name;
+
+ strcpy(newname,pref);
+ strcat(newname,name);
- return follow_path(base, name) ?: name;
+ return stat(newname,&buf) ? name : strdup(newname);
}
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
next reply other threads:[~2007-02-19 14:04 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-19 13:04 Kirill A. Shutemov [this message]
2007-02-23 16:58 ` [Qemu-devel] [PATCH] [REPOST] Simplily linux-user/path.c Thiemo Seufer
2007-03-20 14:41 ` Kirill A. Shutemov
-- strict thread matches above, loose matches on Subject: below --
2007-02-19 14:02 Kirill A. Shutemov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070219130409.GD25556@localhost.localdomain \
--to=k.shutemov@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).