diff --git a/libmaxsi/c/hsrc/unistd.h b/libmaxsi/c/hsrc/unistd.h index 6844a588..6cb2f206 100644 --- a/libmaxsi/c/hsrc/unistd.h +++ b/libmaxsi/c/hsrc/unistd.h @@ -112,7 +112,6 @@ pid_t getpgid(pid_t); pid_t getpgrp(void); pid_t getsid(pid_t); uid_t getuid(void); -int isatty(int); int lchown(const char*, uid_t, gid_t); int link(const char*, const char*); int linkat(int, const char*, int, const char*, int); @@ -162,6 +161,7 @@ pid_t fork(void); char* getcwd(char*, size_t); pid_t getpid(void); pid_t getppid(void); +int isatty(int); int pipe(int [2]); ssize_t read(int, void*, size_t); unsigned sleep(unsigned); diff --git a/libmaxsi/decl/errno_values.h b/libmaxsi/decl/errno_values.h index 08a39af8..a8bf3095 100644 --- a/libmaxsi/decl/errno_values.h +++ b/libmaxsi/decl/errno_values.h @@ -20,5 +20,6 @@ #define ENOEXEC 28 #define EACCESS 29 #define ESRCH 30 +#define ENOTTY 31 #endif diff --git a/libmaxsi/error.cpp b/libmaxsi/error.cpp index b3f4cdd8..7aabd5a7 100644 --- a/libmaxsi/error.cpp +++ b/libmaxsi/error.cpp @@ -63,6 +63,7 @@ namespace Maxsi case ENOEXEC: return (char*) "Not executable"; case EACCESS: return (char*) "Permission denied"; case ESRCH: return (char*) "No such process"; + case ENOTTY: return (char*) "Not a tty"; default: return (char*) "Unknown error condition"; } } diff --git a/libmaxsi/io.cpp b/libmaxsi/io.cpp index db95beb6..a7318240 100644 --- a/libmaxsi/io.cpp +++ b/libmaxsi/io.cpp @@ -47,6 +47,7 @@ namespace Maxsi DEFN_SYSCALL1(int, SysChDir, 25, const char*); DEFN_SYSCALL2(char*, SysGetCWD, 26, char*, size_t); DEFN_SYSCALL1(int, SysUnlink, 27, const char*); + DEFN_SYSCALL1(int, SysIsATTY, 33, int); size_t Print(const char* string) { @@ -161,6 +162,11 @@ namespace Maxsi { return SysUnlink(pathname); } + + extern "C" int isatty(int fd) + { + return SysIsATTY(fd); + } #endif } diff --git a/sortix/device.h b/sortix/device.h index 591f61f9..477d56ce 100644 --- a/sortix/device.h +++ b/sortix/device.h @@ -35,6 +35,7 @@ namespace Sortix static const unsigned VGABUFFER = 2; static const unsigned FILESYSTEM = 3; static const unsigned DIRECTORY = 4; + static const unsigned TTY = 5; public: Device(); diff --git a/sortix/fs/ramfs.cpp b/sortix/fs/ramfs.cpp index 08275590..0879db4f 100644 --- a/sortix/fs/ramfs.cpp +++ b/sortix/fs/ramfs.cpp @@ -51,6 +51,7 @@ namespace Sortix private: size_t offset; byte* buffer; + size_t bufferused; size_t buffersize; public: @@ -70,6 +71,7 @@ namespace Sortix { this->name = name; buffer = NULL; + bufferused = 0; buffersize = 0; } @@ -86,7 +88,7 @@ namespace Sortix uintmax_t DevRAMFSFile::Size() { - return buffersize; + return bufferused; } uintmax_t DevRAMFSFile::Position() @@ -106,10 +108,11 @@ namespace Sortix if ( SIZE_MAX < size ) { Error::Set(EOVERFLOW); return false; } byte* newbuffer = new byte[size]; if ( !newbuffer ) { Error::Set(ENOSPC); return false; } - size_t sharedmemsize = ( size < buffersize ) ? size : buffersize; + size_t sharedmemsize = ( size < bufferused ) ? size : bufferused; Memory::Copy(newbuffer, buffer, sharedmemsize); delete[] buffer; buffer = newbuffer; + bufferused = sharedmemsize; buffersize = size; return true; } @@ -118,7 +121,7 @@ namespace Sortix { if ( SSIZE_MAX < count ) { count = SSIZE_MAX; } size_t available = count; - if ( buffersize < offset + count ) { available = buffersize - offset; } + if ( bufferused < offset + count ) { available = bufferused - offset; } if ( available == 0 ) { return 0; } Memory::Copy(dest, buffer + offset, available); offset += available; @@ -137,6 +140,7 @@ namespace Sortix Memory::Copy(buffer + offset, src, count); offset += count; + if ( bufferused < offset ) { bufferused = offset; } return count; } diff --git a/sortix/io.cpp b/sortix/io.cpp index 96ed233a..c42d9521 100644 --- a/sortix/io.cpp +++ b/sortix/io.cpp @@ -52,13 +52,13 @@ namespace Sortix 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 */ } + if ( !dev ) { Error::Set(EBADF); return -1; } + if ( !dev->IsType(Device::STREAM) ) { Error::Set(EBADF); return -1; } DevStream* stream = (DevStream*) dev; - if ( !stream->IsWritable() ) { return -1; /* TODO: EBADF */ } + if ( !stream->IsWritable() ) { Error::Set(EBADF); return -1; } ssize_t written = stream->Write(buffer, count); if ( 0 <= written ) { return written; } - if ( Error::Last() != EWOULDBLOCK ) { return -1; /* TODO: errno */ } + if ( Error::Last() != EWOULDBLOCK ) { return -1; } // The stream will resume our system call once progress has been // made. Our request is certainly not forgotten. @@ -92,13 +92,13 @@ namespace Sortix 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 */ } + if ( !dev ) { Error::Set(EBADF); return -1; } + if ( !dev->IsType(Device::STREAM) ) { Error::Set(EBADF); return -1; } DevStream* stream = (DevStream*) dev; - if ( !stream->IsReadable() ) { return -1; /* TODO: EBADF */ } + if ( !stream->IsReadable() ) { Error::Set(EBADF); return -1;} ssize_t bytesread = stream->Read(buffer, count); if ( 0 <= bytesread ) { return bytesread; } - if ( Error::Last() != EWOULDBLOCK ) { return -1; /* TODO: errno */ } + if ( Error::Last() != EWOULDBLOCK ) { return -1; } // The stream will resume our system call once progress has been // made. Our request is certainly not forgotten. @@ -121,7 +121,7 @@ namespace Sortix { Process* process = CurrentProcess(); Device* dev = process->descriptors.Get(fd); - if ( !dev ) { return -1; /* TODO: EBADF */ } + if ( !dev ) { Error::Set(EBADF); return -1; } process->descriptors.Free(fd); return 0; } @@ -130,16 +130,26 @@ namespace Sortix { Process* process = CurrentProcess(); Device* dev = process->descriptors.Get(fd); - if ( !dev ) { return -1; /* TODO: EBADF */ } + if ( !dev ) { Error::Set(EBADF); return -1; } return process->descriptors.Allocate(dev); } + int SysIsATTY(int fd) + { + Process* process = CurrentProcess(); + Device* dev = process->descriptors.Get(fd); + if ( !dev ) { Error::Set(EBADF); return 0; } + if ( !dev->IsType(Device::TTY) ) { Error::Set(ENOTTY); return 0; } + return 1; + } + void Init() { Syscall::Register(SYSCALL_WRITE, (void*) SysWrite); Syscall::Register(SYSCALL_READ, (void*) SysRead); Syscall::Register(SYSCALL_CLOSE, (void*) SysClose); Syscall::Register(SYSCALL_DUP, (void*) SysDup); + Syscall::Register(SYSCALL_ISATTY, (void*) SysIsATTY); } } } diff --git a/sortix/syscallnum.h b/sortix/syscallnum.h index 485a413b..9b458fb1 100644 --- a/sortix/syscallnum.h +++ b/sortix/syscallnum.h @@ -58,7 +58,8 @@ #define SYSCALL_SIGRETURN 30 #define SYSCALL_KILL 31 #define SYSCALL_MEMSTAT 32 -#define SYSCALL_MAX_NUM 33 /* index of highest constant + 1 */ +#define SYSCALL_ISATTY 33 +#define SYSCALL_MAX_NUM 34 /* index of highest constant + 1 */ #endif diff --git a/utils/editor.cpp b/utils/editor.cpp index bbca7b5c..65165718 100644 --- a/utils/editor.cpp +++ b/utils/editor.cpp @@ -410,6 +410,8 @@ void run() int main(int argc, char* argv[]) { + if ( !isatty(1) ) { error(1, errno, "stdout must be a tty"); return 1; } + if ( argc < 2 ) { clearbuffers();