Add tcgetwincurpos(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2013-12-20 21:55:05 +01:00
parent d5241349cc
commit eaf1618537
22 changed files with 185 additions and 8 deletions

View File

@ -548,6 +548,11 @@ ssize_t Descriptor::readlink(ioctx_t* ctx, char* buf, size_t bufsize)
return vnode->readlink(ctx, buf, bufsize);
}
int Descriptor::tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp)
{
return vnode->tcgetwincurpos(ctx, wcp);
}
int Descriptor::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
{
return vnode->tcgetwinsize(ctx, ws);

View File

@ -212,6 +212,7 @@ public:
virtual int symlink(ioctx_t* ctx, const char* oldname,
const char* filename);
virtual ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
virtual int tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp);
virtual int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
virtual int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
virtual pid_t tcgetpgrp(ioctx_t* ctx);
@ -1101,6 +1102,23 @@ ssize_t Unode::readlink(ioctx_t* ctx, char* buf, size_t bufsiz)
return ret;
}
int Unode::tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp)
{
Channel* channel = server->Connect();
if ( !channel )
return -1;
int ret = -1;
struct fsm_req_tcgetwincurpos msg;
struct fsm_resp_tcgetwincurpos resp;
msg.ino = ino;
if ( SendMessage(channel, FSM_REQ_TCGETWINCURPOS, &msg, sizeof(msg)) &&
RecvMessage(channel, FSM_RESP_TCGETWINCURPOS, &resp, sizeof(resp)) &&
ctx->copy_to_dest(wcp, &resp.pos, sizeof(*wcp)) )
ret = 0;
channel->KernelClose();
return ret;
}
int Unode::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
{
Channel* channel = server->Connect();

View File

@ -35,6 +35,7 @@
#include <sortix/kernel/refcount.h>
struct stat;
struct wincurpos;
struct winsize;
struct kernel_dirent;
@ -77,6 +78,7 @@ public:
int rmdir(ioctx_t* ctx, const char* filename);
int symlink(ioctx_t* ctx, const char* oldname, const char* filename);
ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
int tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp);
int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
pid_t tcgetpgrp(ioctx_t* ctx);

View File

@ -35,6 +35,7 @@
#include <sortix/kernel/refcount.h>
struct stat;
struct wincurpos;
struct winsize;
struct kernel_dirent;
@ -86,6 +87,7 @@ public:
virtual int symlink(ioctx_t* ctx, const char* oldname,
const char* filename) = 0;
virtual ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz) = 0;
virtual int tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp) = 0;
virtual int tcgetwinsize(ioctx_t* ctx, struct winsize* ws) = 0;
virtual int tcsetpgrp(ioctx_t* ctx, pid_t pgid) = 0;
virtual pid_t tcgetpgrp(ioctx_t* ctx) = 0;
@ -164,6 +166,7 @@ public:
virtual int symlink(ioctx_t* ctx, const char* oldname,
const char* filename);
virtual ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
virtual int tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp);
virtual int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
virtual int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
virtual pid_t tcgetpgrp(ioctx_t* ctx);

View File

@ -36,6 +36,7 @@ namespace Log {
extern size_t (*device_callback)(void*, const char*, size_t);
extern size_t (*device_width)(void*);
extern size_t (*device_height)(void*);
extern void (*device_get_cursor)(void*, size_t*, size_t*);
extern bool (*device_sync)(void*);
extern void* device_pointer;
extern bool (*emergency_device_is_impaired)(void*);
@ -44,6 +45,7 @@ extern void (*emergency_device_reset)(void*);
extern size_t (*emergency_device_callback)(void*, const char*, size_t);
extern size_t (*emergency_device_width)(void*);
extern size_t (*emergency_device_height)(void*);
extern void (*emergency_device_get_cursor)(void*, size_t*, size_t*);
extern bool (*emergency_device_sync)(void*);
extern void* emergency_device_pointer;
@ -64,6 +66,11 @@ inline size_t Height()
return device_height(device_pointer);
}
inline void GetCursor(size_t* col, size_t* row)
{
return device_get_cursor(device_pointer, col, row);
}
inline bool Sync()
{
return device_sync(device_pointer);

View File

@ -25,11 +25,16 @@
#ifndef INCLUDE_SORTIX_KERNEL_VNODE_H
#define INCLUDE_SORTIX_KERNEL_VNODE_H
#include <sys/types.h>
#include <stdint.h>
#include <sortix/timespec.h>
#include <sortix/kernel/refcount.h>
struct stat;
struct wincurpos;
struct winsize;
struct kernel_dirent;
@ -74,6 +79,7 @@ public:
int symlink(ioctx_t* ctx, const char* oldname, const char* filename);
ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
int fsbind(ioctx_t* ctx, Vnode* node, int flags);
int tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp);
int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
pid_t tcgetpgrp(ioctx_t* ctx);

View File

@ -145,6 +145,7 @@
#define SYSCALL_PRLIMIT 121
#define SYSCALL_DUP3 122
#define SYSCALL_SYMLINKAT 123
#define SYSCALL_MAX_NUM 124 /* index of highest constant + 1 */
#define SYSCALL_TCGETWINCURPOS 124
#define SYSCALL_MAX_NUM 125 /* index of highest constant + 1 */
#endif

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
This file is part of Sortix.
@ -22,13 +22,27 @@
*******************************************************************************/
#ifndef SORTIX_TERMIOS_H
#define SORTIX_TERMIOS_H
#ifndef INCLUDE_SORTIX_TERMIOS_H
#define INCLUDE_SORTIX_TERMIOS_H
#include <sys/cdefs.h>
#include <sys/__/types.h>
__BEGIN_DECLS
#ifndef __size_t_defined
#define __size_t_defined
#define __need_size_t
#include <stddef.h>
#endif
struct wincurpos
{
size_t wcp_row;
size_t wcp_col;
};
struct winsize
{
size_t ws_row;

View File

@ -258,6 +258,13 @@ ssize_t AbstractInode::readlink(ioctx_t* /*ctx*/, char* /*buf*/,
return errno = EINVAL, -1;
}
int AbstractInode::tcgetwincurpos(ioctx_t* /*ctx*/, struct wincurpos* /*wcp*/)
{
if ( inode_type == INODE_TYPE_TTY )
return errno = EBADF, -1;
return errno = ENOTTY, -1;
}
int AbstractInode::tcgetwinsize(ioctx_t* /*ctx*/, struct winsize* /*ws*/)
{
if ( inode_type == INODE_TYPE_TTY )

View File

@ -652,6 +652,16 @@ static int sys_isatty(int fd)
return desc->isatty(&ctx);
}
static int sys_tcgetwincurpos(int fd, struct wincurpos* wcp)
{
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
if ( !desc )
return -1;
ioctx_t ctx; SetupUserIOCtx(&ctx);
return desc->tcgetwincurpos(&ctx, wcp);
}
static int sys_tcgetwinsize(int fd, struct winsize* ws)
{
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
@ -1051,6 +1061,7 @@ void Init()
Syscall::Register(SYSCALL_STAT, (void*) sys_stat);
Syscall::Register(SYSCALL_SYMLINKAT, (void*) sys_symlinkat);
Syscall::Register(SYSCALL_TCGETPGRP, (void*) sys_tcgetpgrp);
Syscall::Register(SYSCALL_TCGETWINCURPOS, (void*) sys_tcgetwincurpos);
Syscall::Register(SYSCALL_TCGETWINSIZE, (void*) sys_tcgetwinsize);
Syscall::Register(SYSCALL_TCSETPGRP, (void*) sys_tcsetpgrp);
Syscall::Register(SYSCALL_TRUNCATEAT, (void*) sys_truncateat);

View File

@ -129,6 +129,11 @@ static size_t TextTermHeight(void* user)
return ((TextTerminal*) user)->Height();
}
static void TextTermGetCursor(void* user, size_t* column, size_t* row)
{
((TextTerminal*) user)->GetCursor(column, row);
}
static bool TextTermSync(void* user)
{
return ((TextTerminal*) user)->Sync();
@ -165,6 +170,11 @@ static size_t EmergencyTextTermHeight(void* user)
return ((TextTerminal*) user)->EmergencyHeight();
}
static void EmergencyTextTermGetCursor(void* user, size_t* column, size_t* row)
{
((TextTerminal*) user)->EmergencyGetCursor(column, row);
}
static bool EmergencyTextTermSync(void* user)
{
return ((TextTerminal*) user)->EmergencySync();
@ -206,6 +216,7 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
Log::device_callback = PrintToTextTerminal;
Log::device_width = TextTermWidth;
Log::device_height = TextTermHeight;
Log::device_get_cursor = TextTermGetCursor;
Log::device_sync = TextTermSync;
Log::device_pointer = &textterm;
@ -216,6 +227,7 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo)
Log::emergency_device_callback = EmergencyPrintToTextTerminal;
Log::emergency_device_width = EmergencyTextTermWidth;
Log::emergency_device_height = EmergencyTextTermHeight;
Log::emergency_device_get_cursor = EmergencyTextTermGetCursor;
Log::emergency_device_sync = EmergencyTextTermSync;
Log::emergency_device_pointer = &textterm;

View File

@ -35,6 +35,7 @@ namespace Log {
size_t (*device_callback)(void*, const char*, size_t) = NULL;
size_t (*device_width)(void*) = NULL;
size_t (*device_height)(void*) = NULL;
void (*device_get_cursor)(void*, size_t*, size_t*) = NULL;
bool (*device_sync)(void*) = NULL;
void* device_pointer = NULL;
bool (*emergency_device_is_impaired)(void*) = NULL;
@ -42,6 +43,7 @@ bool (*emergency_device_recoup)(void*) = NULL;
void (*emergency_device_reset)(void*) = NULL;
size_t (*emergency_device_callback)(void*, const char*, size_t) = NULL;
size_t (*emergency_device_width)(void*) = NULL;
void (*emergency_device_get_cursor)(void*, size_t*, size_t*) = NULL;
size_t (*emergency_device_height)(void*) = NULL;
bool (*emergency_device_sync)(void*) = NULL;
void* emergency_device_pointer = NULL;

View File

@ -118,6 +118,19 @@ int LogTerminal::gettermmode(ioctx_t* ctx, unsigned* mode)
return 0;
}
int LogTerminal::tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp)
{
struct wincurpos retwcp;
memset(&retwcp, 0, sizeof(retwcp));
size_t cursor_column, cursor_row;
Log::GetCursor(&cursor_column, &cursor_row);
retwcp.wcp_col = cursor_column;
retwcp.wcp_row = cursor_row;
if ( !ctx->copy_to_dest(wcp, &retwcp, sizeof(retwcp)) )
return -1;
return 0;
}
int LogTerminal::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
{
struct winsize retws;

View File

@ -44,6 +44,7 @@ public:
virtual int sync(ioctx_t* ctx);
virtual ssize_t read(ioctx_t* ctx, uint8_t* buf, size_t count);
virtual ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count);
virtual int tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp);
virtual int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
virtual int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
virtual pid_t tcgetpgrp(ioctx_t* ctx);

View File

@ -77,6 +77,7 @@ void PanicInit()
Log::device_callback = Log::emergency_device_callback;
Log::device_width = Log::emergency_device_width;
Log::device_height = Log::emergency_device_height;
Log::device_get_cursor = Log::emergency_device_get_cursor;
Log::device_sync = Log::emergency_device_sync;
Log::device_pointer = Log::emergency_device_pointer;

View File

@ -91,6 +91,13 @@ size_t TextTerminal::Height() const
return height;
}
void TextTerminal::GetCursor(size_t* column, size_t* row) const
{
ScopedLock lock(&termlock);
*column = this->column;
*row = this->line;
}
bool TextTerminal::Sync()
{
// Reading something from the textbuffer may cause it to block while
@ -203,6 +210,17 @@ size_t TextTerminal::EmergencyHeight() const
return height;
}
void TextTerminal::EmergencyGetCursor(size_t* column, size_t* row) const
{
// This is during a kernel emergency where preemption has been disabled and
// this is the only thread running. Another thread may have been interrupted
// while it held the terminal lock. The best case is if the terminal lock is
// currently unused, which would mean everything is safe.
*column = this->column;
*row = this->line;
}
bool TextTerminal::EmergencySync()
{
// This is during a kernel emergency where preemption has been disabled and

View File

@ -40,6 +40,7 @@ public:
size_t Print(const char* string, size_t stringlen);
size_t Width() const;
size_t Height() const;
void GetCursor(size_t* column, size_t* row) const;
bool Sync();
bool EmergencyIsImpaired();
bool EmergencyRecoup();
@ -47,6 +48,7 @@ public:
size_t EmergencyPrint(const char* string, size_t stringlen);
size_t EmergencyWidth() const;
size_t EmergencyHeight() const;
void EmergencyGetCursor(size_t* column, size_t* row) const;
bool EmergencySync();
private:

View File

@ -221,6 +221,11 @@ int Vnode::fsbind(ioctx_t* /*ctx*/, Vnode* /*node*/, int /*flags*/)
return -1;
}
int Vnode::tcgetwincurpos(ioctx_t* ctx, struct wincurpos* wcp)
{
return inode->tcgetwincurpos(ctx, wcp);
}
int Vnode::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
{
return inode->tcgetwinsize(ctx, ws);

View File

@ -435,6 +435,7 @@ sys/uio/readv.o \
sys/uio/writev.o \
sys/wait/wait.o \
sys/wait/waitpid.o \
termios/tcgetwincurpos.o \
termios/tcgetwinsize.o \
time/clock_getres.o \
time/clock_gettime.o \

View File

@ -343,7 +343,19 @@ struct fsm_resp_tcgetpgrp
pid_t pgid;
};
#define FSM_MSG_NUM 43
#define FSM_REQ_TCGETWINCURPOS 43
struct fsm_req_tcgetwincurpos
{
ino_t ino;
};
#define FSM_RESP_TCGETWINCURPOS 44
struct fsm_resp_tcgetwincurpos
{
struct wincurpos pos;
};
#define FSM_MSG_NUM 45
#if defined(__cplusplus)
} /* extern "C" */

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
This file is part of the Sortix C Library.
@ -24,16 +24,18 @@
/* TODO: POSIX-1.2008 compliance is only partial */
#ifndef _TERMIOS_H
#define _TERMIOS_H 1
#ifndef INCLUDE_TERMIOS_H
#define INCLUDE_TERMIOS_H
#include <sys/cdefs.h>
#include <stddef.h>
#include <sortix/termios.h>
__BEGIN_DECLS
int tcgetwincurpos(int fd, struct wincurpos* wcp);
int tcgetwinsize(int fd, struct winsize* ws);
__END_DECLS

View File

@ -0,0 +1,34 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013.
This file is part of the Sortix C Library.
The Sortix C Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
The Sortix C Library 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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
termios/tcgetwincurpos.cpp
Access to terminal cursor position.
*******************************************************************************/
#include <sys/syscall.h>
#include <termios.h>
DEFN_SYSCALL2(int, sys_tcgetwincurpos, SYSCALL_TCGETWINCURPOS, int, struct wincurpos*);
extern "C" int tcgetwincurpos(int fd, struct wincurpos* ws)
{
return sys_tcgetwincurpos(fd, ws);
}