From 313079483a1a6ae9d145d185b3929550b86b85e1 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Mon, 21 Nov 2011 00:19:55 +0100 Subject: [PATCH] Missing files from the previous two commits. Ooops! --- libmaxsi/c/hsrc/sys/readdirents.h | 48 ++++++++++++++++ sortix/directory.cpp | 94 +++++++++++++++++++++++++++++++ sortix/directory.h | 64 +++++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 libmaxsi/c/hsrc/sys/readdirents.h create mode 100644 sortix/directory.cpp create mode 100644 sortix/directory.h diff --git a/libmaxsi/c/hsrc/sys/readdirents.h b/libmaxsi/c/hsrc/sys/readdirents.h new file mode 100644 index 00000000..424dd2ab --- /dev/null +++ b/libmaxsi/c/hsrc/sys/readdirents.h @@ -0,0 +1,48 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + This file is part of LibMaxsi. + + LibMaxsi is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with LibMaxsi. If not, see . + + sys/readdirents.h + Allows reading directory entries directly from a file descriptor. + +******************************************************************************/ + +#ifndef _SYS_READDIRENTS_H +#define _SYS_READDIRENTS_H 1 + +#include + +__BEGIN_DECLS + +@include(size_t.h) + +// Keep this up to date with +struct sortix_dirent +{ + struct sortix_dirent* d_next; + unsigned char d_type; + size_t d_namelen; + char d_name[]; +}; + +int readdirents(int fd, struct sortix_dirent* dirent, size_t size); + +__END_DECLS + +#endif + diff --git a/sortix/directory.cpp b/sortix/directory.cpp new file mode 100644 index 00000000..085fcc70 --- /dev/null +++ b/sortix/directory.cpp @@ -0,0 +1,94 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with Sortix. If not, see . + + filesystem.cpp + Allows access to stored sequences of bytes in an orderly fashion. + +******************************************************************************/ + +#include "platform.h" +#include +#include +#include +#include "syscall.h" +#include "process.h" +#include "device.h" +#include "directory.h" + +using namespace Maxsi; + +namespace Sortix +{ + namespace Directory + { + int SysReadDirEnts(int fd, sortix_dirent* dirent, size_t size) + { + Process* process = CurrentProcess(); + Device* dev = process->descriptors.Get(fd); + if ( !dev ) { Error::Set(Error::EBADF); return -1; } + if ( !dev->IsType(Device::DIRECTORY) ) { Error::Set(Error::EBADF); return -1; } + DevDirectory* dir = (DevDirectory*) dev; + + sortix_dirent* prev = NULL; + + while ( true ) + { + // Check if we got enough bytes left to tell how many bytes we + // actually needed. + if ( size < sizeof(sortix_dirent) ) + { + if ( prev ) { return 0; } // We did some work. + Error::Set(Error::EINVAL); // Nope, userspace was cheap. + return -1; + } + + // Attempt to read into the space left, and if we managed to + // read at least one record, just say we succeded. The user + // space buffer is empty on the next call, so that'll probably + // succeed. The directory read function will store the number of + // bytes needed in the d_namelen variable and set errno to + // EINVAL such that userspace knows we need a larger buffer. + if ( dir->Read(dirent, size) ) { return (prev) ? 0 : -1; } + + // Insert the current dirent into the single-linked list for + // easy iteration by userspace. + prev->d_next = dirent; + dirent->d_next = NULL; + + // Check for end-of-directory conditions. Signal to userspace + // that we are done by giving them the empty filename. + if ( dirent->d_namelen == 0 ) { return 0; } + + // Alright, we managed to read a dirent. Now let's try reading + // another one (provide as many as we can). + prev = dirent; + size_t bytesused = sizeof(sortix_dirent) + dirent->d_namelen + 1; + size -= bytesused; + dirent = (sortix_dirent*) ( ((byte*) dirent) + bytesused ); + } + } + + void Init() + { + Syscall::Register(SYSCALL_READDIRENTS, (void*) SysReadDirEnts); + } + } +} + + diff --git a/sortix/directory.h b/sortix/directory.h new file mode 100644 index 00000000..dd381a3d --- /dev/null +++ b/sortix/directory.h @@ -0,0 +1,64 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with Sortix. If not, see . + + directory.h + A container for files and other directories. + +******************************************************************************/ + +#ifndef SORTIX_DIRECTORY_H +#define SORTIX_DIRECTORY_H + +#include "device.h" + +namespace Sortix +{ + // Keep this up to date with + struct sortix_dirent + { + struct sortix_dirent* d_next; + unsigned char d_type; + size_t d_namelen; + char d_name[]; + }; + + class DevDirectory : public Device + { + public: + typedef Device BaseClass; + + public: + virtual void Rewind() = 0; + + // Precondition: available is at least sizeof(sortix_dirent). + virtual int Read(sortix_dirent* dirent, size_t available) = 0; + + public: + virtual bool IsType(unsigned type) { return type == Device::DIRECTORY; } + + }; + + namespace Directory + { + void Init(); + } +} + +#endif +