[freenos] [freenos commit] r166 - VirtualFileSystem now returns FileStat and Dirent objects.

  • From: codesite-noreply@xxxxxxxxxx
  • To: freenos@xxxxxxxxxxxxx
  • Date: Mon, 29 Jun 2009 09:19:42 +0000

Author: nieklinnenbank
Date: Mon Jun 29 00:56:11 2009
New Revision: 166

Modified:
   trunk/bin/ls/Main.cpp
   trunk/bin/mknod/SConscript
   trunk/bin/stat/SConscript
   trunk/lib/libexec/SConscript
   trunk/lib/libposix/dirent.cpp
   trunk/lib/libposix/dirent.h
   trunk/lib/libposix/sys/stat.cpp
   trunk/lib/libposix/sys/stat.h
   trunk/srv/filesystem/Device.h
   trunk/srv/filesystem/Directory.h
   trunk/srv/filesystem/File.h
   trunk/srv/filesystem/FileSystemMessage.h
   trunk/srv/filesystem/ext2/Ext2Directory.cpp
   trunk/srv/filesystem/ext2/Ext2FileSystem.cpp
   trunk/srv/filesystem/ext2/Ext2Inode.h
   trunk/srv/filesystem/proc/ProcFileSystem.cpp
   trunk/srv/filesystem/tmp/TmpFileSystem.cpp

Log:
VirtualFileSystem now returns FileStat and Dirent objects.
The POSIX-1.2008 library translates these objects into POSIX-1.2008
specific struct stat's and struct dirent's. These changes fix bug #12.


Modified: trunk/bin/ls/Main.cpp
==============================================================================
--- trunk/bin/ls/Main.cpp       (original)
+++ trunk/bin/ls/Main.cpp       Mon Jun 29 00:56:11 2009
@@ -45,10 +45,21 @@
     while ((dent = readdir(d)))
     {
        /* Coloring. */
-       if (dent->d_type == DT_DIR)
-           printf("%s", BLUE);
-       else
-           printf("%s", WHITE);
+       switch (dent->d_type)
+       {
+           case DT_DIR:
+               printf("%s", BLUE);
+               break;
+       
+           case DT_BLK:
+           case DT_CHR:
+               printf("%s", YELLOW);
+               break;
+       
+           case DT_REG:
+           default:
+               printf("%s", WHITE);
+       }
        printf("%s ", dent->d_name);
     }
     printf("\r\n");

Modified: trunk/bin/mknod/SConscript
==============================================================================
--- trunk/bin/mknod/SConscript  (original)
+++ trunk/bin/mknod/SConscript  Mon Jun 29 00:56:11 2009
@@ -17,5 +17,6 @@

 from build import *

-env = Prepare(target, [ 'libcrt', 'liballoc', 'libposix', 'libexec', 'libc' ]) +env = Prepare(target, [ 'libcrt', 'liballoc', 'libposix', 'libexec', 'libc' ],
+                     [ 'filesystem' ])
env.Program('mknod', [ 'Main.cpp' ], LIBS = env['LIBS'], LIBPATH = env['LIBPATH'])

Modified: trunk/bin/stat/SConscript
==============================================================================
--- trunk/bin/stat/SConscript   (original)
+++ trunk/bin/stat/SConscript   Mon Jun 29 00:56:11 2009
@@ -17,6 +17,7 @@

 from build import *

-env = Prepare(target, [ 'libcrt', 'liballoc', 'libposix', 'libexec', 'libc' ]) +env = Prepare(target, [ 'libcrt', 'liballoc', 'libposix', 'libexec', 'libc' ],
+                     [ 'filesystem' ])
 env.Program('stat',   [ 'Main.cpp' ],
             LIBS = env['LIBS'], LIBPATH = env['LIBPATH'])

Modified: trunk/lib/libexec/SConscript
==============================================================================
--- trunk/lib/libexec/SConscript        (original)
+++ trunk/lib/libexec/SConscript        Mon Jun 29 00:56:11 2009
@@ -20,7 +20,7 @@
 #
 # Target build.
 #
-env = Prepare(target,  [ 'libposix', 'libc' ])
+env = Prepare(target,  [ 'libposix', 'libc' ], [ 'filesystem' ])
 env.Library('libexec', [ 'ELF.cpp', 'ExecutableFormat.cpp' ])

 #

Modified: trunk/lib/libposix/dirent.cpp
==============================================================================
--- trunk/lib/libposix/dirent.cpp       (original)
+++ trunk/lib/libposix/dirent.cpp       Mon Jun 29 00:56:11 2009
@@ -19,13 +19,16 @@
 #include <Allocator.h>
 #include <Config.h>
 #include <FileSystemMessage.h>
+#include <Directory.h>
 #include <errno.h>
 #include "dirent.h"
 #include "fcntl.h"
 #include "unistd.h"
+#include "sys/stat.h"

 DIR * opendir(const char *dirname)
 {
+    Dirent *dirent;
     DIR *dir;
     int fd;
     struct stat st;
@@ -41,23 +44,43 @@
     {
        return (ZERO);
     }
+    /* Allocate Dirents. */
+    dirent = new Dirent[st.st_size / sizeof(Dirent)];
+
     /* Allocate DIR object. */
     dir = new DIR;
     dir->fd        = fd;
-    dir->buffer    = new Dirent[st.st_size / sizeof(Dirent)];
+    dir->buffer    = new struct dirent[st.st_size / sizeof(Dirent)];
     dir->current   = 0;
     dir->count     = 0;
     dir->eof       = false;

     /* Read them all. */
-    if ((e = read(fd, dir->buffer, sizeof(Dirent) * st.st_size)) < 0)
+    if ((e = read(fd, dirent, sizeof(Dirent) * st.st_size)) < 0)
     {
        e = errno;
        closedir(dir);
        errno = e;
        return (ZERO);
     }
+    /* Fill in the dirent structs. */
+    for (Size i = 0; i < st.st_size / sizeof(Dirent); i++)
+    {
+       u8 types[] =
+       {
+           DT_REG,
+           DT_DIR,
+           DT_BLK,
+           DT_CHR,
+           DT_LNK,
+           DT_FIFO,
+           DT_SOCK,
+       };
+       strlcpy(dir->buffer[i].d_name, dirent[i].name, DIRLEN);
+       dir->buffer[i].d_type = types[dirent[i].type];
+    }
     dir->count = e / sizeof(Dirent);
+    delete dirent;

     /* Set errno. */
     errno = ESUCCESS;

Modified: trunk/lib/libposix/dirent.h
==============================================================================
--- trunk/lib/libposix/dirent.h (original)
+++ trunk/lib/libposix/dirent.h Mon Jun 29 00:56:11 2009
@@ -58,7 +58,7 @@
 /**
  * Represents a directory entry.
  */
-typedef struct dirent
+struct dirent
 {
     /** Name of entry. */
     char d_name[DIRLEN];
@@ -79,8 +79,7 @@
     }

 #endif /* CPP */
-}
-Dirent;
+};

 /**
  * A type representing a directory stream.

Modified: trunk/lib/libposix/sys/stat.cpp
==============================================================================
--- trunk/lib/libposix/sys/stat.cpp     (original)
+++ trunk/lib/libposix/sys/stat.cpp     Mon Jun 29 00:56:11 2009
@@ -24,15 +24,21 @@
 int stat(const char *path, struct stat *buf)
 {
     FileSystemMessage msg;
+    FileStat st;

     /* Fill message. */
     msg.action = StatFile;
     msg.buffer = (char *) path;
-    msg.stat   = buf;
+    msg.stat   = &st;

     /* Ask VFS for the information. */
     IPCMessage(VFSSRV_PID, SendReceive, &msg, sizeof(msg));

+    /* Copy information into buf. */
+    if (msg.result == ESUCCESS)
+    {
+       buf->fromFileStat(&st);
+    }
     /* Set errno. */
     errno = msg.result;


Modified: trunk/lib/libposix/sys/stat.h
==============================================================================
--- trunk/lib/libposix/sys/stat.h       (original)
+++ trunk/lib/libposix/sys/stat.h       Mon Jun 29 00:56:11 2009
@@ -18,6 +18,7 @@
 #ifndef __LIBPOSIX_STAT_H
 #define __LIBPOSIX_STAT_H

+#include <FileSystemMessage.h>
 #include <Macros.h>
 #include <Error.h>
 #include "types.h"
@@ -163,8 +164,31 @@
 /**
  * The <sys/stat.h> header shall define the stat structure.
  */
-typedef struct stat
+struct stat
 {
+    /**
+     * Instantiates the structure given an FileStat object.
+     * @param stat FileStat pointer to copy from.
+     */
+    void fromFileStat(FileStat *stat)
+    {
+       mode_t modes[] =
+        {
+           S_IFREG,
+           S_IFDIR,
+           S_IFBLK,
+           S_IFCHR,
+           S_IFLNK,
+           S_IFIFO,
+           S_IFSOCK,
+       };
+       this->st_mode = modes[stat->type];
+        this->st_size = stat->size;
+        this->st_uid  = stat->userID;
+        this->st_gid  = stat->groupID;
+       this->st_dev  = stat->deviceID;
+    }
+
     /** Device ID of device containing file. */
     dev_t st_dev;

@@ -215,8 +239,7 @@

     /** Number of blocks allocated for this object. */
     blkcnt_t st_blocks;
-}
-FileStat;
+};

 /**
  * Get file status.

Modified: trunk/srv/filesystem/Device.h
==============================================================================
--- trunk/srv/filesystem/Device.h       (original)
+++ trunk/srv/filesystem/Device.h       Mon Jun 29 00:56:11 2009
@@ -90,15 +90,15 @@
          */
         Error status(FileSystemMessage *msg)
         {
-           struct stat st;
+           FileStat st;
            Error e;
        
            /* Fill in the status structure. */
-           st.st_mode = type;
-            st.st_size = size;
-            st.st_uid  = uid;
-            st.st_gid  = gid;
-           st.st_dev  = deviceID;
+           st.type = type;
+            st.size = size;
+            st.userID   = uid;
+            st.groupID  = gid;
+           st.deviceID = deviceID;
        
            /* Write to remote process' buffer. */
            if ((e = VMCopy(msg->procID, Write, (Address) &st,

Modified: trunk/srv/filesystem/Directory.h
==============================================================================
--- trunk/srv/filesystem/Directory.h    (original)
+++ trunk/srv/filesystem/Directory.h    Mon Jun 29 00:56:11 2009
@@ -19,10 +19,35 @@
 #define __FILESYSTEM_DIRECTORY_H

 #include <API/VMCopy.h>
-#include <dirent.h>
 #include <List.h>
 #include "File.h"

+/** Maximum length of a filename. */
+#define DIRENT_LEN     64
+
+/**
+ * Describes an entry inside a Directory.
+ */
+typedef struct Dirent
+{
+    /** Name of the file. */
+    char name[DIRENT_LEN];
+
+    /** Type of file. */
+    FileType type;
+
+    /**
+     * Compares this Dirent with another Dirent instance.
+     * @param dir Instance to compare with.
+     * @return True if equal, false otherwise.
+     */
+    bool operator == (struct Dirent *dir)
+    {
+       return strcmp(name, dir->name) == 0;
+    }
+}
+Dirent;
+
 /**
  * In-memory directory object.
  */
@@ -82,13 +107,13 @@
         * @param type File type.
         * @note Entry names must be unique within the same Dirent.
         */
-       virtual void insertEntry(char *name, u8 type)
+       virtual void insertEntry(char *name, FileType type)
        {
            if (!getEntry(name))
            {
                Dirent *d = new Dirent;
-               strlcpy(d->d_name, name, DIRLEN);
-               d->d_type = type;
+               strlcpy(d->name, name, DIRENT_LEN);
+               d->type = type;
                entries.insertTail(d);
                size += sizeof(*d);
            }
@@ -103,7 +128,7 @@
        {
            for (ListIterator<Dirent> i(&entries); i.hasNext(); i++)
            {
-               if (strcmp(i.current()->d_name, name) == 0)
+               if (strcmp(i.current()->name, name) == 0)
                {
                    return i.current();
                }
@@ -119,7 +144,7 @@
        {
            for (ListIterator<Dirent> i(&entries); i.hasNext(); i++)
            {
-               if (strcmp(i.current()->d_name, name) == 0)
+               if (strcmp(i.current()->name, name) == 0)
                {
                    entries.remove(i.current());
                    delete i.current();

Modified: trunk/srv/filesystem/File.h
==============================================================================
--- trunk/srv/filesystem/File.h (original)
+++ trunk/srv/filesystem/File.h Mon Jun 29 00:56:11 2009
@@ -22,7 +22,6 @@
 #include <FreeNOS/Process.h>
 #include <Types.h>
 #include <Error.h>
-#include <sys/stat.h>
 #include "FileSystemMessage.h"

 /**
@@ -153,14 +152,14 @@
         */
        virtual Error status(FileSystemMessage *msg)
        {
-           struct stat st;
+           FileStat st;
            Error e;
        
            /* Fill in the status structure. */
-           st.st_mode = type;
-           st.st_size = size;
-           st.st_uid  = uid;
-           st.st_gid  = gid;
+           st.type     = type;
+           st.size     = size;
+           st.userID   = uid;
+           st.groupID  = gid;
        
            /* Copy to the remote process. */
            if ((e = VMCopy(msg->procID, Write, (Address) &st,

Modified: trunk/srv/filesystem/FileSystemMessage.h
==============================================================================
--- trunk/srv/filesystem/FileSystemMessage.h    (original)
+++ trunk/srv/filesystem/FileSystemMessage.h    Mon Jun 29 00:56:11 2009
@@ -22,7 +22,6 @@
 #include <IPCServer.h>
 #include <Types.h>
 #include <Error.h>
-#include <sys/stat.h>

 /**
  * Actions which may be performed on the filesystem.
@@ -51,14 +50,38 @@
  */
 typedef enum FileType
 {
-    RegularFile         = S_IFREG,
-    DirectoryFile       = S_IFDIR,
-    BlockDeviceFile     = S_IFBLK,
-    CharacterDeviceFile = S_IFCHR,
-    SymlinkFile         = S_IFLNK,
-    FIFOFile            = S_IFIFO,
+    RegularFile         = 0,
+    DirectoryFile       = 1,
+    BlockDeviceFile     = 2,
+    CharacterDeviceFile = 3,
+    SymlinkFile         = 4,
+    FIFOFile            = 5,
+    SocketFile         = 6,
+    UnknownFile                = 7,
 }
 FileType;
+
+/**
+ * Contains file information.
+ */
+typedef struct FileStat
+{
+    /** File type. */
+    FileType type;
+
+    /** Size of the file in bytes. */
+    Size size;
+
+    /** User identity. */
+    UserID userID;
+
+    /** Group identity. */
+    GroupID groupID;
+
+    /** Device identity. */
+    DeviceID deviceID;
+}
+FileStat;

 /** File access permissions. */
 typedef uint FileMode;

Modified: trunk/srv/filesystem/ext2/Ext2Directory.cpp
==============================================================================
--- trunk/srv/filesystem/ext2/Ext2Directory.cpp (original)
+++ trunk/srv/filesystem/ext2/Ext2Directory.cpp Mon Jun 29 00:56:11 2009
@@ -72,8 +72,8 @@
                {
                    return EINVAL;
                }
-               strlcpy(dent.d_name, ext2Dent.name, ext2Dent.nameLength + 1);
-               dent.d_type = EXT2_FILETYPE(ext2Inode);
+               strlcpy(dent.name, ext2Dent.name, ext2Dent.nameLength + 1);
+               dent.type = EXT2_FILETYPE(ext2Inode);

                /* Copy to the remote process. */               
                 if ((e = VMCopy(msg->procID, Write, (Address) &dent,

Modified: trunk/srv/filesystem/ext2/Ext2FileSystem.cpp
==============================================================================
--- trunk/srv/filesystem/ext2/Ext2FileSystem.cpp        (original)
+++ trunk/srv/filesystem/ext2/Ext2FileSystem.cpp        Mon Jun 29 00:56:11 2009
@@ -243,26 +243,16 @@
            /* Create the appropriate in-memory file. */
            switch (EXT2_FILETYPE(inode))
            {
-               case DT_DIR:
+               case DirectoryFile:
                    c = insertFileCache(new Ext2Directory(this, inode),
                                        **i.current());
                    break;
-                       
-               //case DT_DEV:
-               //    c = insertFileCache(new Ext2Device(this, inode),
-               //                      i.current());
-               //    break;
-                       
-               //case DT_FIFO:
-               //case DT_SYM:
-               //case DT_LINK:
-               //case DT_SOCK:
-               case DT_REG:
+
+               case RegularFile:
                    c = insertFileCache(new Ext2File(this, inode),
                                        **i.current());
                    break;

-               case DT_UNKNOWN:
                default:
                    return ZERO;
            }

Modified: trunk/srv/filesystem/ext2/Ext2Inode.h
==============================================================================
--- trunk/srv/filesystem/ext2/Ext2Inode.h       (original)
+++ trunk/srv/filesystem/ext2/Ext2Inode.h       Mon Jun 29 00:56:11 2009
@@ -33,6 +33,7 @@
 #ifndef __FILESYSTEM_EXT2INODE_H
 #define __FILESYSTEM_EXT2INODE_H

+#include <FileSystemMessage.h>
 #include <sys/stat.h>

 /**
@@ -130,14 +131,32 @@
  */

 /**
- * Retrieve POSIX filetype of an Ext2Inode.
+ * Retrieve the FileType of an Ext2Inode.
  * @param i Ext2Inode pointer.
- * @return POSIX filetype.
+ * @return FileType value.
  * @see dirent.h
  * @see stat.h
  */
 #define EXT2_FILETYPE(i) \
-    (((i)->mode & S_IFMT) >> 12)
+    ({ \
+       FileType types[] = \
+       { \
+           UnknownFile, \
+           FIFOFile, \
+           CharacterDeviceFile, \
+           UnknownFile, \
+           DirectoryFile, \
+           UnknownFile, \
+           BlockDeviceFile, \
+           UnknownFile, \
+           RegularFile, \
+           UnknownFile, \
+           SymlinkFile, \
+           UnknownFile, \
+           SocketFile, \
+       }; \
+       types[((i)->mode & S_IFMT) >> 12]; \
+    })

 /**
  * @}

Modified: trunk/srv/filesystem/proc/ProcFileSystem.cpp
==============================================================================
--- trunk/srv/filesystem/proc/ProcFileSystem.cpp        (original)
+++ trunk/srv/filesystem/proc/ProcFileSystem.cpp        Mon Jun 29 00:56:11 2009
@@ -55,8 +55,8 @@
     clearFileCache();

     /* Update root. */
-    rootDir->insertEntry(".", DT_DIR);
-    rootDir->insertEntry("..", DT_DIR);
+    rootDir->insertEntry(".",  DirectoryFile);
+    rootDir->insertEntry("..", DirectoryFile);
     insertFileCache(rootDir, ".");
     insertFileCache(rootDir, "..");

@@ -77,11 +77,11 @@
        
        /* Per-process directory. */
        procDir = new Directory;
-       procDir->insertEntry(".",       DT_DIR);
-       procDir->insertEntry("..",      DT_DIR);
-       procDir->insertEntry("cmdline", DT_REG);
-       procDir->insertEntry("status",  DT_REG);
-       rootDir->insertEntry(tmp,      DT_DIR);
+       procDir->insertEntry(".",       DirectoryFile);
+       procDir->insertEntry("..",      DirectoryFile);
+       procDir->insertEntry("cmdline", DirectoryFile);
+       procDir->insertEntry("status",  DirectoryFile);
+       rootDir->insertEntry(tmp,       DirectoryFile);
        insertFileCache(procDir, "%u",    msg.number);
        insertFileCache(procDir, "%u/.",  msg.number);
        insertFileCache(rootDir, "%u/..", msg.number);

Modified: trunk/srv/filesystem/tmp/TmpFileSystem.cpp
==============================================================================
--- trunk/srv/filesystem/tmp/TmpFileSystem.cpp  (original)
+++ trunk/srv/filesystem/tmp/TmpFileSystem.cpp  Mon Jun 29 00:56:11 2009
@@ -28,8 +28,8 @@
     Directory *rdir = new Directory;

     root = new FileCache(&slash, rdir, ZERO);
-    rdir->insertEntry(".", DT_DIR);
-    rdir->insertEntry("..", DT_DIR);
+    rdir->insertEntry(".",  DirectoryFile);
+    rdir->insertEntry("..", DirectoryFile);
     insertFileCache(rdir, ".");
     insertFileCache(rdir, "..");
 }
@@ -42,15 +42,15 @@
     /* Create the appropriate file type. */
     switch (msg->filetype)
     {
-       case S_IFREG:
+       case RegularFile:
            insertFileCache(new File, "%s", **path->full());
            break;
        
-       case S_IFDIR:
+       case DirectoryFile:
            insertFileCache(new Directory, "%s", **path->full());
            break;
        
-       case S_IFCHR:
+       case CharacterDeviceFile:
            insertFileCache(new Device(msg->deviceID), "%s", **path->full());
            break;
        

Other related posts:

  • » [freenos] [freenos commit] r166 - VirtualFileSystem now returns FileStat and Dirent objects. - codesite-noreply