Added isatty(2), which is used by editor.

This commit is contained in:
Jonas 'Sortie' Termansen 2011-11-26 20:56:45 +01:00
parent 3f50a335bb
commit bd1b1fe3bc
9 changed files with 41 additions and 15 deletions

View File

@ -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);

View File

@ -20,5 +20,6 @@
#define ENOEXEC 28
#define EACCESS 29
#define ESRCH 30
#define ENOTTY 31
#endif

View File

@ -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";
}
}

View File

@ -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
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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();