Added isatty(2), which is used by editor.
This commit is contained in:
parent
3f50a335bb
commit
bd1b1fe3bc
|
@ -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);
|
||||
|
|
|
@ -20,5 +20,6 @@
|
|||
#define ENOEXEC 28
|
||||
#define EACCESS 29
|
||||
#define ESRCH 30
|
||||
#define ENOTTY 31
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue