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 getpgrp(void);
|
||||||
pid_t getsid(pid_t);
|
pid_t getsid(pid_t);
|
||||||
uid_t getuid(void);
|
uid_t getuid(void);
|
||||||
int isatty(int);
|
|
||||||
int lchown(const char*, uid_t, gid_t);
|
int lchown(const char*, uid_t, gid_t);
|
||||||
int link(const char*, const char*);
|
int link(const char*, const char*);
|
||||||
int linkat(int, const char*, int, const char*, int);
|
int linkat(int, const char*, int, const char*, int);
|
||||||
|
@ -162,6 +161,7 @@ pid_t fork(void);
|
||||||
char* getcwd(char*, size_t);
|
char* getcwd(char*, size_t);
|
||||||
pid_t getpid(void);
|
pid_t getpid(void);
|
||||||
pid_t getppid(void);
|
pid_t getppid(void);
|
||||||
|
int isatty(int);
|
||||||
int pipe(int [2]);
|
int pipe(int [2]);
|
||||||
ssize_t read(int, void*, size_t);
|
ssize_t read(int, void*, size_t);
|
||||||
unsigned sleep(unsigned);
|
unsigned sleep(unsigned);
|
||||||
|
|
|
@ -20,5 +20,6 @@
|
||||||
#define ENOEXEC 28
|
#define ENOEXEC 28
|
||||||
#define EACCESS 29
|
#define EACCESS 29
|
||||||
#define ESRCH 30
|
#define ESRCH 30
|
||||||
|
#define ENOTTY 31
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,6 +63,7 @@ namespace Maxsi
|
||||||
case ENOEXEC: return (char*) "Not executable";
|
case ENOEXEC: return (char*) "Not executable";
|
||||||
case EACCESS: return (char*) "Permission denied";
|
case EACCESS: return (char*) "Permission denied";
|
||||||
case ESRCH: return (char*) "No such process";
|
case ESRCH: return (char*) "No such process";
|
||||||
|
case ENOTTY: return (char*) "Not a tty";
|
||||||
default: return (char*) "Unknown error condition";
|
default: return (char*) "Unknown error condition";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace Maxsi
|
||||||
DEFN_SYSCALL1(int, SysChDir, 25, const char*);
|
DEFN_SYSCALL1(int, SysChDir, 25, const char*);
|
||||||
DEFN_SYSCALL2(char*, SysGetCWD, 26, char*, size_t);
|
DEFN_SYSCALL2(char*, SysGetCWD, 26, char*, size_t);
|
||||||
DEFN_SYSCALL1(int, SysUnlink, 27, const char*);
|
DEFN_SYSCALL1(int, SysUnlink, 27, const char*);
|
||||||
|
DEFN_SYSCALL1(int, SysIsATTY, 33, int);
|
||||||
|
|
||||||
size_t Print(const char* string)
|
size_t Print(const char* string)
|
||||||
{
|
{
|
||||||
|
@ -161,6 +162,11 @@ namespace Maxsi
|
||||||
{
|
{
|
||||||
return SysUnlink(pathname);
|
return SysUnlink(pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" int isatty(int fd)
|
||||||
|
{
|
||||||
|
return SysIsATTY(fd);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace Sortix
|
||||||
static const unsigned VGABUFFER = 2;
|
static const unsigned VGABUFFER = 2;
|
||||||
static const unsigned FILESYSTEM = 3;
|
static const unsigned FILESYSTEM = 3;
|
||||||
static const unsigned DIRECTORY = 4;
|
static const unsigned DIRECTORY = 4;
|
||||||
|
static const unsigned TTY = 5;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Device();
|
Device();
|
||||||
|
|
|
@ -51,6 +51,7 @@ namespace Sortix
|
||||||
private:
|
private:
|
||||||
size_t offset;
|
size_t offset;
|
||||||
byte* buffer;
|
byte* buffer;
|
||||||
|
size_t bufferused;
|
||||||
size_t buffersize;
|
size_t buffersize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -70,6 +71,7 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
this->name = name;
|
this->name = name;
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
bufferused = 0;
|
||||||
buffersize = 0;
|
buffersize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +88,7 @@ namespace Sortix
|
||||||
|
|
||||||
uintmax_t DevRAMFSFile::Size()
|
uintmax_t DevRAMFSFile::Size()
|
||||||
{
|
{
|
||||||
return buffersize;
|
return bufferused;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintmax_t DevRAMFSFile::Position()
|
uintmax_t DevRAMFSFile::Position()
|
||||||
|
@ -106,10 +108,11 @@ namespace Sortix
|
||||||
if ( SIZE_MAX < size ) { Error::Set(EOVERFLOW); return false; }
|
if ( SIZE_MAX < size ) { Error::Set(EOVERFLOW); return false; }
|
||||||
byte* newbuffer = new byte[size];
|
byte* newbuffer = new byte[size];
|
||||||
if ( !newbuffer ) { Error::Set(ENOSPC); return false; }
|
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);
|
Memory::Copy(newbuffer, buffer, sharedmemsize);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
buffer = newbuffer;
|
buffer = newbuffer;
|
||||||
|
bufferused = sharedmemsize;
|
||||||
buffersize = size;
|
buffersize = size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +121,7 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
||||||
size_t available = count;
|
size_t available = count;
|
||||||
if ( buffersize < offset + count ) { available = buffersize - offset; }
|
if ( bufferused < offset + count ) { available = bufferused - offset; }
|
||||||
if ( available == 0 ) { return 0; }
|
if ( available == 0 ) { return 0; }
|
||||||
Memory::Copy(dest, buffer + offset, available);
|
Memory::Copy(dest, buffer + offset, available);
|
||||||
offset += available;
|
offset += available;
|
||||||
|
@ -137,6 +140,7 @@ namespace Sortix
|
||||||
|
|
||||||
Memory::Copy(buffer + offset, src, count);
|
Memory::Copy(buffer + offset, src, count);
|
||||||
offset += count;
|
offset += count;
|
||||||
|
if ( bufferused < offset ) { bufferused = offset; }
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,13 +52,13 @@ namespace Sortix
|
||||||
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
||||||
Process* process = CurrentProcess();
|
Process* process = CurrentProcess();
|
||||||
Device* dev = process->descriptors.Get(fd);
|
Device* dev = process->descriptors.Get(fd);
|
||||||
if ( !dev ) { return -1; /* TODO: EBADF */ }
|
if ( !dev ) { Error::Set(EBADF); return -1; }
|
||||||
if ( !dev->IsType(Device::STREAM) ) { return -1; /* TODO: EBADF */ }
|
if ( !dev->IsType(Device::STREAM) ) { Error::Set(EBADF); return -1; }
|
||||||
DevStream* stream = (DevStream*) dev;
|
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);
|
ssize_t written = stream->Write(buffer, count);
|
||||||
if ( 0 <= written ) { return written; }
|
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
|
// The stream will resume our system call once progress has been
|
||||||
// made. Our request is certainly not forgotten.
|
// made. Our request is certainly not forgotten.
|
||||||
|
@ -92,13 +92,13 @@ namespace Sortix
|
||||||
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
if ( SSIZE_MAX < count ) { count = SSIZE_MAX; }
|
||||||
Process* process = CurrentProcess();
|
Process* process = CurrentProcess();
|
||||||
Device* dev = process->descriptors.Get(fd);
|
Device* dev = process->descriptors.Get(fd);
|
||||||
if ( !dev ) { return -1; /* TODO: EBADF */ }
|
if ( !dev ) { Error::Set(EBADF); return -1; }
|
||||||
if ( !dev->IsType(Device::STREAM) ) { return -1; /* TODO: EBADF */ }
|
if ( !dev->IsType(Device::STREAM) ) { Error::Set(EBADF); return -1; }
|
||||||
DevStream* stream = (DevStream*) dev;
|
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);
|
ssize_t bytesread = stream->Read(buffer, count);
|
||||||
if ( 0 <= bytesread ) { return bytesread; }
|
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
|
// The stream will resume our system call once progress has been
|
||||||
// made. Our request is certainly not forgotten.
|
// made. Our request is certainly not forgotten.
|
||||||
|
@ -121,7 +121,7 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
Process* process = CurrentProcess();
|
Process* process = CurrentProcess();
|
||||||
Device* dev = process->descriptors.Get(fd);
|
Device* dev = process->descriptors.Get(fd);
|
||||||
if ( !dev ) { return -1; /* TODO: EBADF */ }
|
if ( !dev ) { Error::Set(EBADF); return -1; }
|
||||||
process->descriptors.Free(fd);
|
process->descriptors.Free(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -130,16 +130,26 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
Process* process = CurrentProcess();
|
Process* process = CurrentProcess();
|
||||||
Device* dev = process->descriptors.Get(fd);
|
Device* dev = process->descriptors.Get(fd);
|
||||||
if ( !dev ) { return -1; /* TODO: EBADF */ }
|
if ( !dev ) { Error::Set(EBADF); return -1; }
|
||||||
return process->descriptors.Allocate(dev);
|
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()
|
void Init()
|
||||||
{
|
{
|
||||||
Syscall::Register(SYSCALL_WRITE, (void*) SysWrite);
|
Syscall::Register(SYSCALL_WRITE, (void*) SysWrite);
|
||||||
Syscall::Register(SYSCALL_READ, (void*) SysRead);
|
Syscall::Register(SYSCALL_READ, (void*) SysRead);
|
||||||
Syscall::Register(SYSCALL_CLOSE, (void*) SysClose);
|
Syscall::Register(SYSCALL_CLOSE, (void*) SysClose);
|
||||||
Syscall::Register(SYSCALL_DUP, (void*) SysDup);
|
Syscall::Register(SYSCALL_DUP, (void*) SysDup);
|
||||||
|
Syscall::Register(SYSCALL_ISATTY, (void*) SysIsATTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,8 @@
|
||||||
#define SYSCALL_SIGRETURN 30
|
#define SYSCALL_SIGRETURN 30
|
||||||
#define SYSCALL_KILL 31
|
#define SYSCALL_KILL 31
|
||||||
#define SYSCALL_MEMSTAT 32
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -410,6 +410,8 @@ void run()
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
if ( !isatty(1) ) { error(1, errno, "stdout must be a tty"); return 1; }
|
||||||
|
|
||||||
if ( argc < 2 )
|
if ( argc < 2 )
|
||||||
{
|
{
|
||||||
clearbuffers();
|
clearbuffers();
|
||||||
|
|
Loading…
Reference in New Issue