From a7de7b4905a127b8e6076a9acaa319e1ab6a7e12 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Wed, 16 Nov 2011 08:37:29 +0100 Subject: [PATCH] Added pipe(2), write(2), and read(2). --- Makefile | 1 - libmaxsi/c/hsrc/unistd.h | 6 +- libmaxsi/hsrc/error.h | 2 + libmaxsi/io.cpp | 19 +++ sortix/Makefile | 2 + sortix/descriptors.cpp | 3 +- sortix/descriptors.h | 2 +- sortix/device.cpp | 19 +-- sortix/device.h | 53 ++----- sortix/io.cpp | 126 +++++++++++++++++ sortix/io.h | 37 +++++ sortix/kernel.cpp | 8 ++ sortix/pipe.cpp | 289 +++++++++++++++++++++++++++++++++++++++ sortix/pipe.h | 40 ++++++ sortix/stream.h | 56 +++----- sortix/syscallnum.h | 5 +- sortix/vga.cpp | 9 +- sortix/vga.h | 6 +- 18 files changed, 578 insertions(+), 105 deletions(-) create mode 100644 sortix/io.cpp create mode 100644 sortix/io.h create mode 100644 sortix/pipe.cpp create mode 100644 sortix/pipe.h diff --git a/Makefile b/Makefile index 4417b50c..bd5b5ff0 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,6 @@ debsource: all mkdir -p $(DEBSRCDIR) for D in `ls | grep -v builds | grep -v sysroot`; do cp -r $$D $(DEBSRCDIR); done (cd $(DEBSRCDIR) && make distclean) - rm $(DEBSRCDIR)/git-daemon-export-ok rm -rf $(DEBSRCDIR)/sysroot (cd builds && tar cfzv $(DEBSRCNAME)-src.tar.gz $(DEBSRCNAME)-src) rm -rf $(DEBSRCDIR) diff --git a/libmaxsi/c/hsrc/unistd.h b/libmaxsi/c/hsrc/unistd.h index bcfea441..f150ce2b 100644 --- a/libmaxsi/c/hsrc/unistd.h +++ b/libmaxsi/c/hsrc/unistd.h @@ -125,10 +125,8 @@ off_t lseek(int, off_t, int); int nice(int); long pathconf(const char*, int); int pause(void); -int pipe(int [2]); ssize_t pread(int, void*, size_t, off_t); ssize_t pwrite(int, const void*, size_t, off_t); -ssize_t read(int, void*, size_t); ssize_t readlink(const char* restrict, char* restrict, size_t); ssize_t readlinkat(int, const char* restrict, char* restrict, size_t); int rmdir(const char*); @@ -152,7 +150,6 @@ char* ttyname(int); int ttyname_r(int, char*, size_t); int unlink(const char*); int unlinkat(int, const char*, int); -ssize_t write(int, const void*, size_t); #if __POSIX_OBSOLETE <= 200801 pid_t setpgrp(void); @@ -166,10 +163,13 @@ void _exit(int); pid_t fork(void); pid_t getpid(void); pid_t getppid(void); +int pipe(int [2]); +ssize_t read(int, void*, size_t); unsigned sleep(unsigned); #if __POSIX_OBSOLETE <= 200112 int usleep(useconds_t useconds); #endif +ssize_t write(int, const void*, size_t); __END_DECLS diff --git a/libmaxsi/hsrc/error.h b/libmaxsi/hsrc/error.h index 123caaaf..4952e1f5 100644 --- a/libmaxsi/hsrc/error.h +++ b/libmaxsi/hsrc/error.h @@ -46,6 +46,8 @@ namespace Maxsi const int ENOTBLK = 12; const int ENODEV = 13; + const int EWOULDBLOCK = 14; + const int EBADF = 15; extern int _errornumber; diff --git a/libmaxsi/io.cpp b/libmaxsi/io.cpp index 86ad8467..6217652c 100644 --- a/libmaxsi/io.cpp +++ b/libmaxsi/io.cpp @@ -30,6 +30,9 @@ namespace Maxsi { DEFN_SYSCALL1(size_t, SysPrint, 4, const char*); + DEFN_SYSCALL3(ssize_t, SysRead, 18, int, void*, size_t); + DEFN_SYSCALL3(ssize_t, SysWrite, 19, int, const void*, size_t); + DEFN_SYSCALL1(int, SysPipe, 20, int*); size_t Print(const char* Message) { @@ -59,6 +62,22 @@ namespace Maxsi va_end(list); return (int) result; } + + extern "C" ssize_t read(int fd, void* buf, size_t count) + { + return SysRead(fd, buf, count); + } + + extern "C" ssize_t write(int fd, const void* buf, size_t count) + { + return SysWrite(fd, buf, count); + } + + extern "C" int pipe(int pipefd[2]) + { + return SysPipe(pipefd); + } + #endif } diff --git a/sortix/Makefile b/sortix/Makefile index 83e58638..646ade9c 100644 --- a/sortix/Makefile +++ b/sortix/Makefile @@ -69,6 +69,8 @@ elf.o \ process.o \ initrd.o \ thread.o \ +io.o \ +pipe.o \ ../libmaxsi/libmaxsi-sortix.a JSOBJS:=$(subst .o,-js.o,$(OBJS)) diff --git a/sortix/descriptors.cpp b/sortix/descriptors.cpp index 8243caea..45cad569 100644 --- a/sortix/descriptors.cpp +++ b/sortix/descriptors.cpp @@ -25,6 +25,7 @@ #include "platform.h" #include #include "descriptors.h" +#include "device.h" using namespace Maxsi; @@ -91,7 +92,7 @@ namespace Sortix if ( devices[index] != reserveddevideptr ) { - // TODO: Unref device here? + devices[index]->Unref(); } devices[index] = NULL; diff --git a/sortix/descriptors.h b/sortix/descriptors.h index 8b02a005..544186af 100644 --- a/sortix/descriptors.h +++ b/sortix/descriptors.h @@ -49,7 +49,7 @@ namespace Sortix public: inline Device* Get(int index) { - if ( numdevices <= index ) { return NULL; } + if ( index < 0 || numdevices <= index ) { return NULL; } return devices[index]; } diff --git a/sortix/device.cpp b/sortix/device.cpp index a2a6b39a..6f9fb277 100644 --- a/sortix/device.cpp +++ b/sortix/device.cpp @@ -28,29 +28,24 @@ namespace Sortix { - bool Device::Close() + Device::Device() { - _refCount--; - if ( _refCount == 0 ) - { - delete this; - } - return true; + refcount = 0; } - void Device::Think() + Device::~Device() { } - void Device::RequestThink() + void Device::Unref() { - Think(); + if ( --refcount == 0 ) { delete this; } } - bool Device::Sync() + void Device::Refer() { - return true; + refcount++; } } diff --git a/sortix/device.h b/sortix/device.h index 808a6847..216a3efb 100644 --- a/sortix/device.h +++ b/sortix/device.h @@ -27,61 +27,26 @@ namespace Sortix { - class User; - class Device { public: - // Flags - static const nat READABLE = (1<<0); - static const nat WRITABLE = (1<<1); - static const nat SEEKABLE = (1<<2); - static const nat SIZEABLE = (1<<3); - static const nat BLOCK = (1<<4); - static const nat FLAGMASK = ((1<<5)-1); - - // Types - static const nat TYPEMASK = ~FLAGMASK; - static const nat STREAM = (1<<5); - static const nat BUFFER = (2<<5); - static const nat DIRECTORY = (3<<5); - static const nat FILESYSTEM = (4<<5); - static const nat NETWORK = (5<<5); - static const nat SOUND = (6<<5); - static const nat GRAPHICS = (7<<5); - static const nat MOUSE = (8<<5); - static const nat KEYBOARD = (9<<5); - static const nat PRINTER = (10<<5); - static const nat SCANNER = (11<<5); - static const nat VGABUFFER = (12<<5); - static const nat OTHER = TYPEMASK; + static const unsigned STREAM = 0; + static const unsigned BUFFER = 1; + static const unsigned VGABUFFER = 2; public: - volatile size_t _refCount; - - public: - Device() { _refCount = 1; } - virtual ~Device() { } + Device(); + virtual ~Device(); private: - User* _owner; + size_t refcount; public: - bool IsOwner(User* candidate) { return candidate == _owner; } + void Refer(); + void Unref(); public: - bool Close(); - void RequestThink(); - - protected: - virtual void Think(); - - public: - virtual bool Sync(); - virtual nat Flags() = 0; - - public: - bool IsType(nat type) { return (Flags() & TYPEMASK) == type; } + virtual bool IsType(unsigned type) = 0; }; } diff --git a/sortix/io.cpp b/sortix/io.cpp new file mode 100644 index 00000000..75bba0f4 --- /dev/null +++ b/sortix/io.cpp @@ -0,0 +1,126 @@ +/****************************************************************************** + + 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 . + + io.cpp + Provides system calls for input and output. + +******************************************************************************/ + +#include "platform.h" +#include +#include "thread.h" +#include "process.h" +#include "device.h" +#include "stream.h" +#include "syscall.h" +#include "io.h" + +using namespace Maxsi; + +namespace Sortix +{ + namespace IO + { + struct SysWrite_t + { + union { size_t align1; int fd; }; + union { size_t align2; const byte* buffer; }; + union { size_t align3; size_t count; }; + }; + + STATIC_ASSERT(sizeof(SysWrite_t) <= sizeof(Thread::scstate)); + + ssize_t SysWrite(int fd, const byte* buffer, size_t count) + { + // TODO: Check that buffer is a valid user-space buffer. + if ( SSIZE_MAX < count ) { count = SSIZE_MAX; } + Process* process = CurrentProcess(); + Device* dev = process->descriptors.Get(fd); + if ( !dev ) { return -1; /* TODO: EBADF */ } + if ( !dev->IsType(Device::STREAM) ) { return -1; /* TODO: EBADF */ } + DevStream* stream = (DevStream*) dev; + if ( !stream->IsWritable() ) { return -1; /* TODO: EBADF */ } + ssize_t written = stream->Write(buffer, count); + if ( 0 <= written ) { return written; } + if ( Error::Last() != Error::EWOULDBLOCK ) { return -1; /* TODO: errno */ } + + // The stream will resume our system call once progress has been + // made. Our request is certainly not forgotten. + + // Resume the system call with these parameters. + Thread* thread = CurrentThread(); + thread->scfunc = (void*) SysWrite; + SysWrite_t* state = (SysWrite_t*) thread->scstate; + state->fd = fd; + state->buffer = buffer; + state->count = count; + thread->scsize = sizeof(SysWrite_t); + + // Now go do something else. + Syscall::Incomplete(); + return 0; + } + + struct SysRead_t + { + union { size_t align1; int fd; }; + union { size_t align2; byte* buffer; }; + union { size_t align3; size_t count; }; + }; + + STATIC_ASSERT(sizeof(SysRead_t) <= sizeof(Thread::scstate)); + + ssize_t SysRead(int fd, byte* buffer, size_t count) + { + // TODO: Check that buffer is a valid user-space buffer. + if ( SSIZE_MAX < count ) { count = SSIZE_MAX; } + Process* process = CurrentProcess(); + Device* dev = process->descriptors.Get(fd); + if ( !dev ) { return -1; /* TODO: EBADF */ } + if ( !dev->IsType(Device::STREAM) ) { return -1; /* TODO: EBADF */ } + DevStream* stream = (DevStream*) dev; + if ( !stream->IsReadable() ) { return -1; /* TODO: EBADF */ } + ssize_t bytesread = stream->Read(buffer, count); + if ( 0 <= bytesread ) { return bytesread; } + if ( Error::Last() != Error::EWOULDBLOCK ) { return -1; /* TODO: errno */ } + + // The stream will resume our system call once progress has been + // made. Our request is certainly not forgotten. + + // Resume the system call with these parameters. + Thread* thread = CurrentThread(); + thread->scfunc = (void*) SysRead; + SysRead_t* state = (SysRead_t*) thread->scstate; + state->fd = fd; + state->buffer = buffer; + state->count = count; + thread->scsize = sizeof(SysRead_t); + + // Now go do something else. + Syscall::Incomplete(); + return 0; + } + + void Init() + { + Syscall::Register(SYSCALL_WRITE, (void*) SysWrite); + Syscall::Register(SYSCALL_READ, (void*) SysRead); + } + } +} diff --git a/sortix/io.h b/sortix/io.h new file mode 100644 index 00000000..164b6a6a --- /dev/null +++ b/sortix/io.h @@ -0,0 +1,37 @@ +/****************************************************************************** + + 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 . + + io.h + Provides system calls for input and output. + +******************************************************************************/ + +#ifndef SORTIX_IO_H +#define SORTIX_IO_H + +namespace Sortix +{ + namespace IO + { + void Init(); + } +} + +#endif + diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp index dd878d28..785a7b99 100644 --- a/sortix/kernel.cpp +++ b/sortix/kernel.cpp @@ -45,6 +45,8 @@ #include "initrd.h" #include "vga.h" #include "sound.h" +#include "io.h" +#include "pipe.h" using namespace Maxsi; @@ -236,6 +238,12 @@ namespace Sortix // Initialize the process system. Process::Init(); + // Initialize the IO system. + IO::Init(); + + // Initialize the pipe system. + Pipe::Init(); + // Initialize the scheduler. Scheduler::Init(); diff --git a/sortix/pipe.cpp b/sortix/pipe.cpp new file mode 100644 index 00000000..ac0dd49e --- /dev/null +++ b/sortix/pipe.cpp @@ -0,0 +1,289 @@ +/****************************************************************************** + + 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 . + + pipe.cpp + A device with a writing end and a reading end. + +******************************************************************************/ + +#include "platform.h" +#include +#include +#include "thread.h" +#include "process.h" +#include "syscall.h" +#include "pipe.h" + +using namespace Maxsi; + +namespace Sortix +{ + class DevPipeStorage : public DevStream + { + public: + typedef Device BaseClass; + + public: + DevPipeStorage(byte* buffer, size_t buffersize); + ~DevPipeStorage(); + + private: + byte* buffer; + size_t buffersize; + size_t bufferoffset; + size_t bufferused; + Thread* readwaiting; + Thread* writewaiting; + + public: + virtual ssize_t Read(byte* dest, size_t count); + virtual ssize_t Write(const byte* src, size_t count); + virtual bool IsReadable(); + virtual bool IsWritable(); + + }; + + DevPipeStorage::DevPipeStorage(byte* buffer, size_t buffersize) + { + this->buffer = buffer; + this->buffersize = buffersize; + this->bufferoffset = 0; + this->bufferused = 0; + this->readwaiting = NULL; + this->writewaiting = NULL; + } + + DevPipeStorage::~DevPipeStorage() + { + ASSERT(!readwaiting); + ASSERT(!writewaiting); + delete[] buffer; + } + + bool DevPipeStorage::IsReadable() { return true; } + bool DevPipeStorage::IsWritable() { return true; } + + ssize_t DevPipeStorage::Read(byte* dest, size_t count) + { + if ( count == 0 ) { return 0; } + if ( bufferused ) + { + if ( bufferused < count ) { count = bufferused; } + size_t amount = count; + size_t linear = buffersize - bufferused; + if ( linear < amount ) { amount = linear; } + Memory::Copy(dest, buffer + bufferoffset, amount); + bufferoffset = (bufferoffset + amount) % buffersize; + bufferused -= amount; + if ( writewaiting ) + { + Syscall::ScheduleResumption(writewaiting); + writewaiting = NULL; + } + if ( bufferused == 0 || amount == count ) { return amount; } + return amount + Read(dest + amount, count - amount); + } + + Error::Set(Error::EWOULDBLOCK); + + // TODO: Only one thread can wait on a pipe at the same time. + ASSERT(readwaiting == NULL); + readwaiting = CurrentThread(); + return -1; + } + + ssize_t DevPipeStorage::Write(const byte* src, size_t count) + { + if ( count == 0 ) { return 0; } + if ( bufferused < buffersize ) + { + if ( buffersize - bufferused < count ) { count = buffersize - bufferused; } + size_t writeoffset = (bufferoffset + bufferused) % buffersize; + size_t amount = count; + size_t linear = buffersize - writeoffset; + if ( linear < amount ) { amount = linear; } + Memory::Copy(buffer + writeoffset, src, amount); + bufferused += amount; + if ( readwaiting ) + { + Syscall::ScheduleResumption(readwaiting); + readwaiting = NULL; + } + if ( buffersize == bufferused || amount == count ) { return amount; } + return amount + Write(src + amount, count - amount); + } + + Error::Set(Error::EWOULDBLOCK); + + // TODO: Only one thread can wait on a pipe at the same time. + ASSERT(writewaiting == NULL); + writewaiting = CurrentThread(); + return -1; + } + + class DevPipeReading : public DevStream + { + public: + typedef Device BaseClass; + + public: + DevPipeReading(DevStream* stream); + ~DevPipeReading(); + + private: + DevStream* stream; + + public: + virtual ssize_t Read(byte* dest, size_t count); + virtual ssize_t Write(const byte* src, size_t count); + virtual bool IsReadable(); + virtual bool IsWritable(); + + }; + + DevPipeReading::DevPipeReading(DevStream* stream) + { + stream->Refer(); + this->stream = stream; + } + + DevPipeReading::~DevPipeReading() + { + stream->Unref(); + } + + ssize_t DevPipeReading::Read(byte* dest, size_t count) + { + return stream->Read(dest, count); + } + + ssize_t DevPipeReading::Write(const byte* /*src*/, size_t /*count*/) + { + Error::Set(Error::EBADF); + return -1; + } + + bool DevPipeReading::IsReadable() + { + return true; + } + + bool DevPipeReading::IsWritable() + { + return false; + } + + class DevPipeWriting : public DevStream + { + public: + typedef Device BaseClass; + + public: + DevPipeWriting(DevStream* stream); + ~DevPipeWriting(); + + private: + DevStream* stream; + + public: + virtual ssize_t Read(byte* dest, size_t count); + virtual ssize_t Write(const byte* src, size_t count); + virtual bool IsReadable(); + virtual bool IsWritable(); + + }; + + DevPipeWriting::DevPipeWriting(DevStream* stream) + { + stream->Refer(); + this->stream = stream; + } + + DevPipeWriting::~DevPipeWriting() + { + stream->Unref(); + } + + ssize_t DevPipeWriting::Read(byte* /*dest*/, size_t /*count*/) + { + Error::Set(Error::EBADF); + return -1; + } + + ssize_t DevPipeWriting::Write(const byte* src, size_t count) + { + return stream->Write(src, count); + } + + bool DevPipeWriting::IsReadable() + { + return false; + } + + bool DevPipeWriting::IsWritable() + { + return true; + } + + namespace Pipe + { + const size_t BUFFER_SIZE = 4096UL; + + int SysPipe(int pipefd[2]) + { + // TODO: Validate that pipefd is a valid user-space array! + + size_t buffersize = BUFFER_SIZE; + byte* buffer = new byte[buffersize]; + if ( !buffer ) { return -1; /* TODO: ENOMEM */ } + + // Transfer ownership of the buffer to the storage device. + DevStream* storage = new DevPipeStorage(buffer, buffersize); + if ( !storage ) { delete[] buffer; return -1; /* TODO: ENOMEM */ } + + DevStream* reading = new DevPipeReading(storage); + if ( !reading ) { delete storage; return -1; /* TODO: ENOMEM */ } + + DevStream* writing = new DevPipeWriting(storage); + if ( !writing ) { delete reading; return -1; /* TODO: ENOMEM */ } + + Process* process = CurrentProcess(); + int readfd = process->descriptors.Allocate(reading); + int writefd = process->descriptors.Allocate(writing); + + if ( readfd < 0 || writefd < 0 ) + { + if ( 0 <= readfd ) { process->descriptors.Free(readfd); } else { delete reading; } + if ( 0 <= writefd ) { process->descriptors.Free(writefd); } else { delete writing; } + + return -1; /* TODO: ENOMEM/EMFILE/ENFILE */ + } + + pipefd[0] = readfd; + pipefd[1] = writefd; + + return 0; + } + + void Init() + { + Syscall::Register(SYSCALL_PIPE, (void*) SysPipe); + } + } +} diff --git a/sortix/pipe.h b/sortix/pipe.h new file mode 100644 index 00000000..3f7587ac --- /dev/null +++ b/sortix/pipe.h @@ -0,0 +1,40 @@ +/****************************************************************************** + + 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 . + + pipe.h + A device with a writing end and a reading end. + +******************************************************************************/ + + +#ifndef SORTIX_PIPE_H +#define SORTIX_PIPE_H + +#include "stream.h" + +namespace Sortix +{ + namespace Pipe + { + void Init(); + } +} + +#endif + diff --git a/sortix/stream.h b/sortix/stream.h index 97fd31e6..c028b035 100644 --- a/sortix/stream.h +++ b/sortix/stream.h @@ -25,61 +25,43 @@ #ifndef SORTIX_STREAM_H #define SORTIX_STREAM_H +#include "device.h" + namespace Sortix { - class Device - { - public: - Device() { }; - virtual ~Device() { } - - public: - virtual void close() = 0; - - }; - class DevStream : public Device { public: - DevStream() { }; - virtual ~DevStream() { } + typedef Device BaseClass; public: - virtual size_t write(const void* buffer, size_t bufferSize) = 0; - virtual size_t readSome(const void* buffer, size_t bufferSize) = 0; + virtual bool IsType(unsigned type) { return type == Device::STREAM; } public: - inline size_t read(const void* buffer, size_t bufferSize) - { - const uint8_t* bytes = (uint8_t*) buffer; - size_t total = bufferSize; - while ( BufferSize > 0 ) - { - size_t got = readSome(bytes, bufferSize); - if ( got == SIZE_MAX ) { return SIZE_MAX; } - bytes += got; - bufferSize -= got; - } - return total; - } + virtual ssize_t Read(byte* dest, size_t count) = 0; + virtual ssize_t Write(const byte* src, size_t count) = 0; + virtual bool IsReadable() = 0; + virtual bool IsWritable() = 0; + }; class DevBuffer : public DevStream { public: - DevBuffer() { }; - virtual ~DevBuffer() { } + typedef Device BaseClass; public: - virtual size_t write(const void* buffer, size_t bufferSize) = 0; - virtual size_t readSome(const void* buffer, size_t bufferSize) = 0; + virtual bool IsType(unsigned type) + { + return type == Device::BUFFER || BaseClass::IsType(type); + } public: - virtual size_t blockSize() = 0; - virtual intmax_t size() = 0; - virtual intmax_t position() = 0; - virtual bool seek(intmax_t position) = 0; - virtual bool resize(intmax_t size) = 0; + virtual size_t BlockSize() = 0; + virtual uintmax_t Size() = 0; + virtual uintmax_t Position() = 0; + virtual bool Seek(uintmax_t position) = 0; + virtual bool Resize(uintmax_t size) = 0; }; } diff --git a/sortix/syscallnum.h b/sortix/syscallnum.h index e5e42c99..c420ea7f 100644 --- a/sortix/syscallnum.h +++ b/sortix/syscallnum.h @@ -43,7 +43,10 @@ #define SYSCALL_GET_FILEINFO 15 #define SYSCALL_GET_NUM_FILES 16 #define SYSCALL_WAIT 17 -#define SYSCALL_MAX_NUM 18 /* index of highest constant + 1 */ +#define SYSCALL_READ 18 +#define SYSCALL_WRITE 19 +#define SYSCALL_PIPE 20 +#define SYSCALL_MAX_NUM 21 /* index of highest constant + 1 */ #endif diff --git a/sortix/vga.cpp b/sortix/vga.cpp index 6fbe7a82..80747c88 100644 --- a/sortix/vga.cpp +++ b/sortix/vga.cpp @@ -109,6 +109,8 @@ namespace Sortix frame->physical = page; frame->userframe = userframe; + frame->Refer(); + return mapto; } @@ -185,7 +187,7 @@ namespace Sortix process->descriptors.Free(fd); if ( device == NULL ) { return -1; } - if ( !device->Close() ) { return -1; } + device->Unref(); return 0; } @@ -206,5 +208,8 @@ namespace Sortix if ( physical != 0 ) { Page::Put(physical); } } - nat DevVGAFrame::Flags() { return Device::VGABUFFER; } + bool DevVGAFrame::IsType(unsigned type) + { + return type == Device::VGABUFFER; + } } diff --git a/sortix/vga.h b/sortix/vga.h index 75c0c356..a00dded6 100644 --- a/sortix/vga.h +++ b/sortix/vga.h @@ -71,13 +71,13 @@ namespace Sortix class DevVGAFrame : public Device { - public: - virtual nat Flags(); - public: DevVGAFrame(); ~DevVGAFrame(); + public: + virtual bool IsType(unsigned type); + public: Process* process; addr_t physical;