Another idea about getting rid of having to read the /proc/self/
namespace.
Hilko Bengen
bengen@hidden
Tue Jan 20 00:34:14 CET 2009
Hi Mike,
here's another try for building internal representations of a
directory without having to use the /proc fs. I am not sure if saving
the current working directory is needed at all, but I left it in to be
sure.
I haven't tried compiling it on an etch system, but a quick look into
manual pages showed that fchdir() is available there. On my sid system
it compiles and the tests run fine.
Handling the "." and ".." special cases seemed to make more sense
within the add_entry() method, so I moved them there.
Cheers,
-Hilko
diff --git a/kernel/file.cpp b/kernel/file.cpp
index 0f54dcb..4dc3dba 100644
--- a/kernel/file.cpp
+++ b/kernel/file.cpp
@@ -417,25 +417,55 @@ bool directory_t::match(unicode_string_t &name) const
void directory_t::add_entry(const char *name)
{
- char fullname[MAX_PATH];
- sprintf(fullname, "/proc/self/fd/%d/%s", get_fd(), name);
+ int cwd;
dprintf("adding dir entry: %s\n", name);
directory_entry_t *ent = new directory_entry_t;
+ if ( (cwd=::open(".", O_DIRECTORY)) == -1 )
+ {
+ dprintf("failed open current directory (%d).\n", errno);
+ return;
+ }
+ if ( fchdir(get_fd()) == -1 )
+ {
+ dprintf("fchdir() feilad (%d).\n", errno);
+ goto end;
+ }
ent->name.copy(name);
- if (0 != stat(fullname, &ent->st))
+ if (0 != stat(name, &ent->st))
{
delete ent;
- return;
+ goto end;
}
if (!match(ent->name))
{
delete ent;
- return;
+ goto end;
}
dprintf("matched mask %pus\n", &mask);
//dprintf("mode = %o\n", ent->st.st_mode);
- entries.append(ent);
+ if (strcmp(name, ".") == 0)
+ {
+ entries.prepend(ent);
+ }
+ else if (strcmp(name, "..") == 0)
+ {
+ if (entries.head()->name.Length == 2 &&
+ entries.head()->name.Buffer[0] == '.')
+ entries.insert_after(entries.head(), ent);
+ else
+ entries.prepend(ent);
+ }
+ else
+ {
+ entries.append(ent);
+ }
count++;
+end:
+ if ( fchdir(cwd) == -1 )
+ {
+ dprintf("fchdir() failed (%d)\n", errno);
+ }
+ ::close(cwd);
}
int directory_t::get_num_entries() const
@@ -457,9 +487,6 @@ void directory_t::scandir()
}
dprintf("reading entries:\n");
- // . and .. always come first
- add_entry(".");
- add_entry("..");
do
{
@@ -480,8 +507,6 @@ void directory_t::scandir()
if (de->d_reclen <=0 )
break;
ofs += de->d_reclen;
- if (!strcmp(de->d_name,".") || !strcmp(de->d_name, ".."))
- continue;
add_entry(de->d_name);
}
} while (0);
More information about the ring3k
mailing list