Add tcgetwincurpos(2).
This commit is contained in:
parent
d5241349cc
commit
eaf1618537
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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" */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue