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;