mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Added readdirents(2), which ls(1) now uses, and added dir devices.
The initfs and ramfs are now able to list their contents.
This commit is contained in:
parent
e3bb0dfc9d
commit
23fde42249
13 changed files with 230 additions and 12 deletions
|
@ -39,6 +39,7 @@ c/h/stdarg.h \
|
|||
c/h/wctype.h \
|
||||
c/h/features.h \
|
||||
c/h/string.h \
|
||||
c/h/sys/readdirents.h \
|
||||
c/h/sys/stat.h \
|
||||
c/h/sys/types.h \
|
||||
c/h/sys/wait.h \
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace Maxsi
|
|||
const int ENOSPC = 18;
|
||||
const int EEXIST = 19;
|
||||
const int EROFS = 20;
|
||||
const int EINVAL = 21;
|
||||
const int ENOTDIR = 22;
|
||||
|
||||
extern int _errornumber;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "syscall.h"
|
||||
#include "io.h"
|
||||
#include "format.h"
|
||||
#include <sys/readdirents.h>
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
|
@ -36,6 +37,7 @@ namespace Maxsi
|
|||
DEFN_SYSCALL1(int, SysClose, 21, int);
|
||||
DEFN_SYSCALL1(int, SysDup, 22, int);
|
||||
DEFN_SYSCALL3(int, SysOpen, 23, const char*, int, mode_t);
|
||||
DEFN_SYSCALL3(int, SysReadDirEnts, 24, int, struct sortix_dirent*, size_t);
|
||||
|
||||
size_t Print(const char* Message)
|
||||
{
|
||||
|
@ -95,6 +97,11 @@ namespace Maxsi
|
|||
{
|
||||
return SysOpen(path, flags, mode);
|
||||
}
|
||||
|
||||
extern "C" int readdirents(int fd, struct sortix_dirent* dirent, size_t size)
|
||||
{
|
||||
return SysReadDirEnts(fd, dirent, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ thread.o \
|
|||
io.o \
|
||||
pipe.o \
|
||||
filesystem.o \
|
||||
directory.o \
|
||||
mount.o \
|
||||
fs/initfs.o \
|
||||
fs/ramfs.o \
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Sortix
|
|||
static const unsigned BUFFER = 1;
|
||||
static const unsigned VGABUFFER = 2;
|
||||
static const unsigned FILESYSTEM = 3;
|
||||
static const unsigned DIRECTORY = 4;
|
||||
|
||||
public:
|
||||
Device();
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <libmaxsi/string.h>
|
||||
#include <libmaxsi/memory.h>
|
||||
#include "../filesystem.h"
|
||||
#include "../directory.h"
|
||||
#include "../stream.h"
|
||||
#include "initfs.h"
|
||||
#include "../initrd.h"
|
||||
|
@ -133,6 +134,65 @@ namespace Sortix
|
|||
return false;
|
||||
}
|
||||
|
||||
class DevInitFSDir : public DevDirectory
|
||||
{
|
||||
public:
|
||||
typedef Device DevDirectory;
|
||||
|
||||
public:
|
||||
DevInitFSDir();
|
||||
virtual ~DevInitFSDir();
|
||||
|
||||
private:
|
||||
size_t position;
|
||||
|
||||
public:
|
||||
virtual void Rewind();
|
||||
virtual int Read(sortix_dirent* dirent, size_t available);
|
||||
|
||||
};
|
||||
|
||||
DevInitFSDir::DevInitFSDir()
|
||||
{
|
||||
position = 0;
|
||||
}
|
||||
|
||||
DevInitFSDir::~DevInitFSDir()
|
||||
{
|
||||
}
|
||||
|
||||
void DevInitFSDir::Rewind()
|
||||
{
|
||||
position = 0;
|
||||
}
|
||||
|
||||
int DevInitFSDir::Read(sortix_dirent* dirent, size_t available)
|
||||
{
|
||||
if ( available <= sizeof(sortix_dirent) ) { return -1; }
|
||||
if ( InitRD::GetNumFiles() <= position )
|
||||
{
|
||||
dirent->d_namelen = 0;
|
||||
dirent->d_name[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* name = InitRD::GetFilename(position);
|
||||
size_t namelen = String::Length(name);
|
||||
size_t needed = sizeof(sortix_dirent) + namelen + 1;
|
||||
|
||||
if ( available < needed )
|
||||
{
|
||||
dirent->d_namelen = needed;
|
||||
Error::Set(Error::EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Memory::Copy(dirent->d_name, name, namelen + 1);
|
||||
dirent->d_namelen = namelen;
|
||||
position++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DevInitFS::DevInitFS()
|
||||
{
|
||||
}
|
||||
|
@ -143,11 +203,20 @@ namespace Sortix
|
|||
|
||||
Device* DevInitFS::Open(const char* path, int flags, mode_t mode)
|
||||
{
|
||||
size_t buffersize;
|
||||
|
||||
if ( (flags & O_LOWERFLAGS) == O_SEARCH )
|
||||
{
|
||||
if ( path[0] == 0 || (path[0] == '/' && path[1] == 0) ) { return new DevInitFSDir; }
|
||||
const byte* buffer = InitRD::Open(path, &buffersize);
|
||||
Error::Set(buffer ? Error::ENOTDIR : Error::ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( *path++ != '/' ) { return NULL; }
|
||||
|
||||
if ( (flags & O_LOWERFLAGS) != O_RDONLY ) { Error::Set(Error::EROFS); return NULL; }
|
||||
|
||||
size_t buffersize;
|
||||
const byte* buffer = InitRD::Open(path, &buffersize);
|
||||
if ( !buffer ) { Error::Set(Error::ENOENT); return NULL; }
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <libmaxsi/string.h>
|
||||
#include <libmaxsi/memory.h>
|
||||
#include "../filesystem.h"
|
||||
#include "../directory.h"
|
||||
#include "../stream.h"
|
||||
#include "ramfs.h"
|
||||
|
||||
|
@ -162,6 +163,70 @@ namespace Sortix
|
|||
}
|
||||
}
|
||||
|
||||
class DevRAMFSDir : public DevDirectory
|
||||
{
|
||||
public:
|
||||
typedef Device DevDirectory;
|
||||
|
||||
public:
|
||||
DevRAMFSDir(DevRAMFS* fs);
|
||||
virtual ~DevRAMFSDir();
|
||||
|
||||
private:
|
||||
DevRAMFS* fs;
|
||||
size_t position;
|
||||
|
||||
public:
|
||||
virtual void Rewind();
|
||||
virtual int Read(sortix_dirent* dirent, size_t available);
|
||||
|
||||
};
|
||||
|
||||
DevRAMFSDir::DevRAMFSDir(DevRAMFS* fs)
|
||||
{
|
||||
position = 0;
|
||||
this->fs = fs;
|
||||
fs->Refer();
|
||||
}
|
||||
|
||||
DevRAMFSDir::~DevRAMFSDir()
|
||||
{
|
||||
fs->Unref();
|
||||
}
|
||||
|
||||
void DevRAMFSDir::Rewind()
|
||||
{
|
||||
position = 0;
|
||||
}
|
||||
|
||||
int DevRAMFSDir::Read(sortix_dirent* dirent, size_t available)
|
||||
{
|
||||
if ( available <= sizeof(sortix_dirent) ) { return -1; }
|
||||
if ( fs->GetNumFiles() <= position )
|
||||
{
|
||||
dirent->d_namelen = 0;
|
||||
dirent->d_name[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* name = fs->GetFilename(position);
|
||||
if ( !name ) { return -1; }
|
||||
size_t namelen = String::Length(name);
|
||||
size_t needed = sizeof(sortix_dirent) + namelen + 1;
|
||||
|
||||
if ( available < needed )
|
||||
{
|
||||
dirent->d_namelen = needed;
|
||||
Error::Set(Error::EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Memory::Copy(dirent->d_name, name, namelen + 1);
|
||||
dirent->d_namelen = namelen;
|
||||
position++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CompareFiles(DevRAMFSFile* file1, DevRAMFSFile* file2)
|
||||
{
|
||||
return String::Compare(file1->name, file2->name);
|
||||
|
@ -174,6 +239,13 @@ namespace Sortix
|
|||
|
||||
Device* DevRAMFS::Open(const char* path, int flags, mode_t mode)
|
||||
{
|
||||
if ( (flags & O_LOWERFLAGS) == O_SEARCH )
|
||||
{
|
||||
if ( path[0] == 0 || (path[0] == '/' && path[1] == 0) ) { return new DevRAMFSDir(this); }
|
||||
Error::Set(Error::ENOTDIR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DevBuffer* file = OpenFile(path, flags, mode);
|
||||
if ( !file ) { return NULL; }
|
||||
Device* wrapper = new DevFileWrapper(file, flags);
|
||||
|
@ -224,5 +296,19 @@ namespace Sortix
|
|||
|
||||
return file;
|
||||
}
|
||||
|
||||
size_t DevRAMFS::GetNumFiles()
|
||||
{
|
||||
if ( !files ) { return 0; }
|
||||
return files->Length();
|
||||
}
|
||||
|
||||
const char* DevRAMFS::GetFilename(size_t index)
|
||||
{
|
||||
if ( !files ) { return NULL; }
|
||||
if ( files->Length() <= index ) { return NULL; }
|
||||
DevRAMFSFile* file = files->Get(index);
|
||||
return file->name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Sortix
|
|||
|
||||
class DevRAMFS : public DevFileSystem
|
||||
{
|
||||
public:
|
||||
public:
|
||||
DevRAMFS();
|
||||
virtual ~DevRAMFS();
|
||||
|
||||
|
@ -44,6 +44,10 @@ namespace Sortix
|
|||
private:
|
||||
Maxsi::SortedList<DevRAMFSFile*>* files;
|
||||
|
||||
public:
|
||||
size_t GetNumFiles();
|
||||
const char* GetFilename(size_t index);
|
||||
|
||||
private:
|
||||
virtual DevBuffer* OpenFile(const char* path, int flags, mode_t mode);
|
||||
virtual DevBuffer* CreateFile(const char* path, int flags, mode_t mode);
|
||||
|
|
|
@ -50,12 +50,26 @@ namespace Sortix
|
|||
}
|
||||
}
|
||||
|
||||
size_t SysGetNumFiles()
|
||||
size_t GetNumFiles()
|
||||
{
|
||||
Header* header = (Header*) initrd;
|
||||
return header->numfiles;
|
||||
}
|
||||
|
||||
size_t SysGetNumFiles()
|
||||
{
|
||||
return GetNumFiles();
|
||||
}
|
||||
|
||||
const char* GetFilename(size_t index)
|
||||
{
|
||||
Header* header = (Header*) initrd;
|
||||
if ( index >= header->numfiles ) { return NULL; }
|
||||
FileHeader* fhtbl = (FileHeader*) (initrd + sizeof(Header));
|
||||
FileHeader* fileheader = &(fhtbl[index]);
|
||||
return fileheader->name;
|
||||
}
|
||||
|
||||
struct FileInfo
|
||||
{
|
||||
mode_t permissions;
|
||||
|
|
|
@ -52,6 +52,8 @@ namespace Sortix
|
|||
#ifdef SORTIX_KERNEL
|
||||
void Init(byte* initrd, size_t size);
|
||||
byte* Open(const char* filepath, size_t* size);
|
||||
const char* GetFilename(size_t index);
|
||||
size_t GetNumFiles();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "pipe.h"
|
||||
#include "filesystem.h"
|
||||
#include "mount.h"
|
||||
#include "directory.h"
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
|
@ -249,6 +250,9 @@ namespace Sortix
|
|||
// Initialize the filesystem system.
|
||||
FileSystem::Init();
|
||||
|
||||
// Initialize the directory system.
|
||||
Directory::Init();
|
||||
|
||||
// Initialize the mount system.
|
||||
Mount::Init();
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
#define SYSCALL_CLOSE 21
|
||||
#define SYSCALL_DUP 22
|
||||
#define SYSCALL_OPEN 23
|
||||
#define SYSCALL_MAX_NUM 24 /* index of highest constant + 1 */
|
||||
#define SYSCALL_READDIRENTS 24
|
||||
#define SYSCALL_MAX_NUM 25 /* index of highest constant + 1 */
|
||||
|
||||
#endif
|
||||
|
||||
|
|
42
utils/ls.cpp
42
utils/ls.cpp
|
@ -1,18 +1,44 @@
|
|||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/readdirents.h>
|
||||
#include <libmaxsi/platform.h>
|
||||
#include <libmaxsi/process.h>
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
int ls(const char* path)
|
||||
{
|
||||
int fd = open(path, O_SEARCH | O_DIRECTORY);
|
||||
if ( fd < 0 ) { printf("ls: %s: open() failed\n", path); return 2; }
|
||||
|
||||
const size_t BUFFER_SIZE = 512;
|
||||
char buffer[BUFFER_SIZE];
|
||||
sortix_dirent* dirent = (sortix_dirent*) buffer;
|
||||
|
||||
// TODO: Hack until mountpoints work correctly.
|
||||
if ( strcmp(path, "/") == 0 ) { printf("bin\n"); }
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( readdirents(fd, dirent, BUFFER_SIZE) )
|
||||
{
|
||||
printf("readdirents() failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for ( sortix_dirent* iter = dirent; iter; iter = iter->d_next )
|
||||
{
|
||||
if ( iter->d_namelen == 0 ) { return 0; }
|
||||
printf("%s\n", iter->d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
size_t numfiles = Process::GetNumFiles();
|
||||
for ( size_t i = 0; i < numfiles; i++ )
|
||||
{
|
||||
FileInfo fileinfo;
|
||||
Process::GetFileInfo(i, &fileinfo);
|
||||
printf("%s\n", fileinfo.name);
|
||||
}
|
||||
const char* path = "/";
|
||||
if ( 1 < argc ) { path = argv[1]; }
|
||||
|
||||
return 0;
|
||||
return ls(path);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue