diff --git a/libmaxsi/c/hsrc/fcntl.h b/libmaxsi/c/hsrc/fcntl.h
index ecb24876..04d032f4 100644
--- a/libmaxsi/c/hsrc/fcntl.h
+++ b/libmaxsi/c/hsrc/fcntl.h
@@ -46,7 +46,7 @@ __BEGIN_DECLS
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
-#define O_CREAT 0100
+#define O_CREAT (1<<5)
#define O_EXCL 0200
#define O_NOCTTY 0400
#define O_TRUNC 01000
@@ -82,10 +82,10 @@ struct _flock
typedef struct _flock flock;
/* TODO: These are not implemented in libmaxsi/sortix yet. */
+int open(const char* path, int oflag, ...);
#ifndef SORTIX_UNIMPLEMENTED
int creat(const char* path, mode_t mode);
int fcntl(int fd, int cmd, ...);
-int open(const char* path, int oflag, ...);
int openat(int fd, const char* path, int oflag, ...);
#endif
diff --git a/libmaxsi/io.cpp b/libmaxsi/io.cpp
index be89feab..09aea619 100644
--- a/libmaxsi/io.cpp
+++ b/libmaxsi/io.cpp
@@ -35,6 +35,7 @@ namespace Maxsi
DEFN_SYSCALL1(int, SysPipe, 20, int*);
DEFN_SYSCALL1(int, SysClose, 21, int);
DEFN_SYSCALL1(int, SysDup, 22, int);
+ DEFN_SYSCALL3(int, SysOpen, 23, const char*, int, mode_t);
size_t Print(const char* Message)
{
@@ -89,6 +90,11 @@ namespace Maxsi
{
return SysDup(fd);
}
+
+ extern "C" int open(const char* path, int flags, mode_t mode)
+ {
+ return SysOpen(path, flags, mode);
+ }
#endif
}
diff --git a/sortix/Makefile b/sortix/Makefile
index 646ade9c..8d54c525 100644
--- a/sortix/Makefile
+++ b/sortix/Makefile
@@ -71,6 +71,8 @@ initrd.o \
thread.o \
io.o \
pipe.o \
+filesystem.o \
+mount.o \
../libmaxsi/libmaxsi-sortix.a
JSOBJS:=$(subst .o,-js.o,$(OBJS))
diff --git a/sortix/filesystem.cpp b/sortix/filesystem.cpp
new file mode 100644
index 00000000..9079ae92
--- /dev/null
+++ b/sortix/filesystem.cpp
@@ -0,0 +1,60 @@
+/******************************************************************************
+
+ 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 "syscall.h"
+#include "process.h"
+#include "filesystem.h"
+#include "mount.h"
+
+namespace Sortix
+{
+ namespace FileSystem
+ {
+ Device* Open(const char* path, int flags, mode_t mode)
+ {
+ size_t pathoffset = 0;
+ DevFileSystem* fs = Mount::WhichFileSystem(path, &pathoffset);
+ if ( !fs ) { return NULL; }
+ return fs->Open(path + pathoffset, flags, mode);
+ }
+
+ int SysOpen(const char* path, int flags, mode_t mode)
+ {
+ Process* process = CurrentProcess();
+ Device* dev = Open(path, flags, mode);
+ if ( !dev ) { return -1; /* TODO: errno */ }
+ int fd = process->descriptors.Allocate(dev);
+ if ( fd < 0 ) { dev->Unref(); }
+ return fd;
+ }
+
+ void Init()
+ {
+ Syscall::Register(SYSCALL_OPEN, (void*) SysOpen);
+ }
+ }
+}
+
+
diff --git a/sortix/filesystem.h b/sortix/filesystem.h
index 592d394a..ad734967 100644
--- a/sortix/filesystem.h
+++ b/sortix/filesystem.h
@@ -18,7 +18,7 @@
with Sortix. If not, see .
filesystem.h
- Abstracts away a file system device.
+ Allows access to stored sequences of bytes in an orderly fashion.
******************************************************************************/
@@ -26,71 +26,41 @@
#define SORTIX_FILESYSTEM_H
#include "device.h"
-#include "mount.h"
namespace Sortix
{
- class Thread;
-
- namespace FileSystem
- {
- struct SysCallback
- {
- Device* device;
- union { int deviceError; nat deviceType; }
- }
- }
-
// TODO: These belong in libmaxsi!
-
- const nat O_RDONLY = 1;
- const nat O_WRONLY = 2;
- const nat O_RDWR = 3;
- const nat O_EXEC = 4;
- const nat O_SEARCH = 5;
- const nat O_LOWERFLAGS = 0x7;
-
// TODO: Sortix might never support all of these flags if they are stupid.
- const nat O_APPEND = (1<<3);
- const nat O_CLOEXEC = (1<<4);
- const nat O_CREAT = (1<<5);
- const nat O_DIRECTORY = (1<<6);
- const nat O_DSYNC = (1<<6);
- const nat O_EXCL = (1<<7);
- const nat O_NOCTTY = (1<<8);
- const nat O_NOFOLLOW = (1<<9);
- const nat O_RSYNC = (1<<11);
- const nat O_SYNC = (1<<12);
- const nat O_TRUNC = (1<<13);
- const nat O_TTY_INIT = (1<<13);
-
- // If O_RDONLY, then no one is allowed to write to this, or if O_RDWD then
- // no one else is allowed to use this besides me.
- const nat O_EXCLUSIVELY = (1<<14);
- const nat O_USERSPACEABLE = ((1<<15)-1);
-
- const nat O_MOUNT = (1<<31);
+ const int O_RDONLY = 1;
+ const int O_WRONLY = 2;
+ const int O_RDWR = 3;
+ const int O_EXEC = 4;
+ const int O_SEARCH = 5;
+ const int O_LOWERFLAGS = 0x7;
+ const int O_APPEND = (1<<3);
+ const int O_CLOEXEC = (1<<4);
+ const int O_CREAT = (1<<5);
+ const int O_DIRECTORY = (1<<6);
+ const int O_DSYNC = (1<<6);
+ const int O_EXCL = (1<<7);
+ const int O_NOCTTY = (1<<8);
+ const int O_NOFOLLOW = (1<<9);
+ const int O_RSYNC = (1<<11);
+ const int O_SYNC = (1<<12);
+ const int O_TRUNC = (1<<13);
+ const int O_TTY_INIT = (1<<13);
class DevFileSystem : public Device
{
public:
- DevFileSystem() { };
- virtual ~DevFileSystem() { }
-
- public:
- bool LegalNodeName(const char* name);
-
- public:
- virtual int Initialize(MountPoint* mountPoint, const char* commandLine) = 0;
-
- public:
- virtual bool Open(const char* path, nat openFlags, nat mode, FileSystem::SysCallback* callbackInfo, Thread* thread);
+ virtual Device* Open(const char* path, int flags, mode_t mode) = 0;
};
namespace FileSystem
{
- DevFileSystem* CreateDriver(const char* fsType);
+ void Init();
+ Device* Open(const char* path, int flags, mode_t mode);
}
}
diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp
index 785a7b99..093f8b58 100644
--- a/sortix/kernel.cpp
+++ b/sortix/kernel.cpp
@@ -47,6 +47,8 @@
#include "sound.h"
#include "io.h"
#include "pipe.h"
+#include "filesystem.h"
+#include "mount.h"
using namespace Maxsi;
@@ -244,6 +246,12 @@ namespace Sortix
// Initialize the pipe system.
Pipe::Init();
+ // Initialize the filesystem system.
+ FileSystem::Init();
+
+ // Initialize the mount system.
+ Mount::Init();
+
// Initialize the scheduler.
Scheduler::Init();
diff --git a/sortix/mount.cpp b/sortix/mount.cpp
index dddcda92..57127662 100644
--- a/sortix/mount.cpp
+++ b/sortix/mount.cpp
@@ -23,283 +23,22 @@
******************************************************************************/
#include "platform.h"
-#include
-#include "device.h"
-#include "filesystem.h"
-#include "thread.h"
-#include "process.h"
-#include "memorymanagement.h"
+#include "mount.h"
namespace Sortix
{
- namespace Syscall
- {
- void SysOpen(Thread* thread)
- {
- struct Parameters
- {
- struct
- {
- const char* USER userPath SYSPARAM;
- nat openFlags SYSPARAM;
- nat mode SYSPARAM;
- };
- struct
- {
- int handle;
- bool pending;
- FileSystem::SysCallback callbackInfo;
- const char* safePath;
- };
- };
-
- // We store our parameters and data inside the thread object, and we
- // are passed parameters in a special way, so make sure it works.
- STATIC_ASSERT(0 * sizeof(size_t) == offsetof(Parameters, userPath));
- STATIC_ASSERT(1 * sizeof(size_t) == offsetof(Parameters, openflags));
- STATIC_ASSERT(2 * sizeof(size_t) == offsetof(Parameters, mode));
- STATIC_ASSERT(sizeof(Parameters) <= sizeof(thread->sysParams));
- Parameters* params = (Parameters*) thread->sysParams;
-
- int handle;
- const char* path;
-
- // Initialize our variables and validate parameters.
- if ( !thread->sysParamsInited )
- {
- thread->sysParamsInited = true;
- params->handle = handle = -1;
- params->pending = false;
-
- // Make sure the path is a valid string in userspace.
- params->safePath = path = ValidateUserString(params->userPath)
- if ( path == NULL ) { thread->SysReturnError(-1); return; }
-
- params->openFlags &= O_USERSPACEABLE;
- }
- else
- {
- path = params->safePath;
- handle = param->handle;
- }
-
- // Get a descriptor for our device.
- if ( handle == -1 )
- {
- param->handle = handle = thread->GetProcess()->_descs.Reserve();
- if ( handle < 0 ) { thread->SysReturnError(handle); return; }
- }
-
- // Attempt to open the path. If the operation is blocking, this
- // function will re-called when it completes, successful or not.
- if ( !params->pending )
- {
- params->pending = true;
-
- MountPoint* mount = Mount::GetMountPoint(path);
- if ( mount == NULL ) { Error::Set(Error::BADINPUT); thread->SysReturnError(-1); return; }
-
- if ( !mount->fs->Open(path, params->openFlags, params->mode, ¶ms->callbackInfo, thread) ) { return; }
- }
-
- // Return an error if the open failed.
- if ( unlikely(params->callbackInfo.device == NULL) )
- {
- handle = thread->GetProcess()->_descs.Free(handle);
- Error::Set(params->callbackInfo.deviceError);
- thread->SysReturnError(-1); return;
- }
-
- // Bind the device to the descriptor and return it.
- handle = thread->GetProcess()->_descs.UseReservation(handle, params->callbackInfo.device);
- thread->SysReturn(handle); return;
- }
-
- void SysMount(Thread* thread)
- {
- struct Parameters
- {
- struct
- {
- const char* USER userDevicePath SYSPARAM;
- const char* USER userTargetPath SYSPARAM;
- const char* USER userDriverName SYSPARAM;
- nat mode SYSPARAM;
- };
- struct
- {
- int stage;
- DevBuffer* storage;
- DevFileSystem* fsDriver;
- DevDirectory* directory;
- FileSystem::SysCallback callbackInfo;
- };
- };
-
- // We store our parameters and data inside the thread object, and we
- // are passed parameters in a special way, so make sure it works.
- STATIC_ASSERT(0 * sizeof(size_t) == offsetof(Parameters, userDevicePath));
- STATIC_ASSERT(1 * sizeof(size_t) == offsetof(Parameters, userTargetPath));
- STATIC_ASSERT(2 * sizeof(size_t) == offsetof(Parameters, userDriverName));
- STATIC_ASSERT(3 * sizeof(size_t) == offsetof(Parameters, mode));
- STATIC_ASSERT(sizeof(Parameters) <= sizeof(thread->sysParams));
- Parameters* params = (Parameters*) thread->sysParams;
-
- // Initialize our variables and validate parameters.
- if ( !thread->sysParamsInited )
- {
- thread->sysParamsInited = true;
- if ( ValidateUserString(params->userDevicePath) == NULL ||
- ValidateUserString(params->userTargetPath) == NULL ||
- ( params->userDriverName != NULL &&
- ValidateUserString(params->userDriverName) == NULL ) )
- {
- thread->SysReturnError(-1); return;
- }
-
- params->mode &= O_USERSPACEABLE;
- nat baseMode = params->mode & O_LOWERFLAGS;
- nat extMode = params->mode & (~O_LOWERFLAGS);
-
- // Deny unsupported open modes.
- if ( (baseMode != O_RDWR && baseMode != O_RDONLY) ||
- (extMode != 0 && extMode != O_EXCLUSIVELY && extMode != O_SYNC) )
- {
- Error::Set(Error::BADINPUT);
- thread->SysReturnError(-1); return;
- }
-
- params->stage = 0;
- params->storage = NULL;
- params->fsDriver = NULL;
- params->directory = NULL;
- }
-
- MountPoint* mount;
- Device* device = NULL;
-
- switch ( params->stage )
- {
- // Get a handle to the storage device.
- case 0: params->stage++;
-
- mount = Mount::GetMountPoint(¶ms->userDevicePath);
- if ( mount == NULL ) { Error::Set(Error::BADINPUT); break; }
-
- ASSERT(params->mode & O_USERSPACEABLE == 0);
- if ( !mount->fs->Open(params->userDevicePath, params->mode | O_EXCLUSIVELY, 0, ¶ms->callbackInfo, thread) ) { return; }
-
- // Validate the properness of the storage device.
- case 1: params->stage++;
- device = params->callbackInfo.device;
-
- // Did it exist/could we open it/did we have permission?
- if ( unlikely(device == NULL) ) { Error::Set(params->callbackInfo.deviceError); break; }
-
- // Is it a buffer?
- if ( unlikely(!device->IsType(Device::BUFFER)) ) { Error::Set(Error::ENOTBLK); break; }
-
- params->storage = (DevBuffer*) device; device = NULL;
-
- // Get a handle to the destination directory.
- case 2: params->stage++;
-
- mount = Mount::GetMountPoint(¶ms->userTargetPath);
- if ( mount == NULL ) { Error::Set(Error::BADINPUT); break; }
-
- // TODO: Figure out some good mode flags here!
- // TODO: Make sure the FS driver forces the dest dir to be empty!
- if ( !mount->fs->Open(params->userTargetPath, O_RDWR | O_DIRECTORY | O_MOUNT, 0, ¶ms->callbackInfo, thread) ) { return; }
-
- // Validate the properness of the destination directory.
- case 2: params->stage++;
- device = params->callbackInfo.device;
-
- // Did it exist/could we open it?
- if ( unlikely(device == NULL) ) { Error::Set(params->callbackInfo.deviceError); break; }
-
- // Is it a directory?
- if ( unlikely(!device->IsType(Device::DIRECTORY)) ) { Error::Set(Error::ENOTDIR); break; }
-
- params->directory = (DevDirectory*) device; device = NULL;
-
- // Validate that the user owns the directory.
- if ( !params->directory->IsOwner(thread->GetProcess()->GetUser()) ) { Error::Set(Error::EPERM); break; }
-
- // TODO: Add a run-time assertion that the dir is empty!
-
- // Load the proper driver for this file system type.
- case 3: params->stage++;
-
- // TODO: Make an async interface that can scan a device!
- params->fsDriver = FileSystem::CreateDriver(params->userDriverName);
- if ( params->fsDriver == NULL ) { Error::Set(Error::ENODEV); break; }
-
- // Now bind the file system driver to the device and directory.
- case 4: params->stage++;
- MountPoint* newMount = new MountPoint();
-
- newMount->device = params->storage;
- newMount->fs = params->fsDriver;
-
- // TODO: Actually do the mounting!
-
- // Check if everything went well.
- case 4:
- // TODO: Check if everything went well!
- thread->SysReturn(0); return;
- }
-
- if ( device != NULL ) { device->close(); }
- if ( params->storage != NULL ) { params->storage->close(); }
- if ( params->directory != NULL ) { params->directory->close(); }
- if ( params->fsDriver != NULL ) { params->fsDriver->close(); }
-
- thread->SysReturnError(-1); return;
- }
- }
-
namespace Mount
{
- MountPoint* GetMountPoint(const char** path, Thread* thread)
+ DevFileSystem* WhichFileSystem(const char* path, size_t* pathoffset)
{
- ASSERT(path != NULL);
- ASSERT(*path != NULL);
- ASSERT(thread != NULL);
+ // TODO: Support some file systems!
+ *pathoffset = 0;
+ return NULL;
+ }
- if ( unlikely(**path != '/') ) { return NULL; } (*path)++;
- MountPoint* currentFS = thread->GetProcess->GetRootFS();
-
- ASSERT(currentFS != NULL);
-
- // Simply check if path belongs to a child mount point.
- for ( MountPoint* considering = currentFS->child; considering != NULL; considering = considering->nextSibling )
- {
- ASSERT(considering->IsSane());
-
- size_t consideringPathLen = String::Length(considering->path);
- if ( String::CompareN(*path, considering->path, consideringPathLen) == 0 )
- {
- // Check if this is the right dir!
- char lastChar = (*path)[consideringPathLen];
-
- if ( lastChar == '/' ) { (*path) += consideringPathLen + 1; }
- else if ( lastChar == '\0' ) { (*path) += consideringPathLen + 0; }
- else { continue; }
-
- // Check if the mountpoint isn't ready.
- if ( considering->waiting != NULL ) { Error::Set(Error::EBUSY); return NULL; }
-
- currentFS = considering;
- considering = currentFS->child;
- }
- }
-
- ASSERT(currentFS->fs != NULL);
-
- return currentFS;
+ void Init()
+ {
+
}
}
}
-
-
diff --git a/sortix/mount.h b/sortix/mount.h
index a56781d8..b6e7a624 100644
--- a/sortix/mount.h
+++ b/sortix/mount.h
@@ -27,47 +27,12 @@
namespace Sortix
{
- class Device;
class DevFileSystem;
- class DevBuffer;
- class Process;
-
- class MountPoint
- {
- public:
- MountPoint();
- ~MountPoint();
-
- public:
- const char* path;
- DevFileSystem* fs;
- DevBuffer* device;
- nat flags;
-
- public:
- Thread* waiting;
- int* waitingResult;
-
- public:
- bool Mount();
-
- public:
- bool IsSane() { return path != NULL && fs != NULL && device != NULL; }
-
- };
namespace Mount
{
void Init();
- MountPoint* GetMountPoint(const char*& path, Thread* thread);
- void OnMountFailure(MountPoint* mountPoint, int cause);
- void OnMountSuccess(MountPoint* mountPoint);
- }
-
- namespace Syscall
- {
- void SysOpen(Thread* thread);
- void SysMount(Thread* thread);
+ DevFileSystem* WhichFileSystem(const char* path, size_t* pathoffset);
}
}
diff --git a/sortix/syscallnum.h b/sortix/syscallnum.h
index a9678856..03883372 100644
--- a/sortix/syscallnum.h
+++ b/sortix/syscallnum.h
@@ -48,7 +48,8 @@
#define SYSCALL_PIPE 20
#define SYSCALL_CLOSE 21
#define SYSCALL_DUP 22
-#define SYSCALL_MAX_NUM 23 /* index of highest constant + 1 */
+#define SYSCALL_OPEN 23
+#define SYSCALL_MAX_NUM 24 /* index of highest constant + 1 */
#endif