Add tcgetblob(2) and tcsetblob(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2014-05-05 21:36:40 +02:00
parent d6067f9da7
commit 01402052f6
16 changed files with 276 additions and 3 deletions

View File

@ -640,4 +640,22 @@ int Descriptor::setsockopt(ioctx_t* ctx, int level, int option_name,
return vnode->setsockopt(ctx, level, option_name, option_value, option_size);
}
ssize_t Descriptor::tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count)
{
if ( name && !name[0] )
name = NULL;
if ( (size_t) SSIZE_MAX < count )
count = (size_t) SSIZE_MAX;
return vnode->tcgetblob(ctx, name, buffer, count);
}
ssize_t Descriptor::tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count)
{
if ( name && !name[0] )
name = NULL;
if ( (size_t) SSIZE_MAX < count )
return errno = EFBIG, -1;
return vnode->tcsetblob(ctx, name, buffer, count);
}
} // namespace Sortix

View File

@ -236,6 +236,8 @@ public:
void* option_value, size_t* option_size_ptr);
virtual int setsockopt(ioctx_t* ctx, int level, int option_name,
const void* option_value, size_t option_size);
virtual ssize_t tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count);
virtual ssize_t tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count);
private:
bool SendMessage(Channel* channel, size_t type, void* ptr, size_t size,
@ -1348,6 +1350,57 @@ int Unode::setsockopt(ioctx_t* ctx, int level, int option_name,
return ret;
}
ssize_t Unode::tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count)
{
Channel* channel = server->Connect();
if ( !channel )
return -1;
if ( !buffer )
count = SSIZE_MAX;
ssize_t ret = -1;
size_t namelen = name ? strlen(name) : 0;
struct fsm_req_tcgetblob msg;
struct fsm_resp_tcgetblob resp;
msg.ino = ino;
msg.namelen = namelen;
if ( SendMessage(channel, FSM_REQ_TCGETBLOB, &msg, sizeof(msg), namelen) &&
channel->KernelSend(&kctx, name, namelen) &&
RecvMessage(channel, FSM_RESP_TCGETBLOB, &resp, sizeof(resp)) )
{
if ( resp.count < count )
count = resp.count;
if ( count < resp.count )
errno = ERANGE;
else if ( !buffer || channel->KernelRecv(ctx, buffer, count) )
ret = (ssize_t) count;
}
channel->KernelClose();
return ret;
}
ssize_t Unode::tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count)
{
Channel* channel = server->Connect();
if ( !channel )
return -1;
ssize_t ret = -1;
size_t namelen = name ? strlen(name) : 0;
if ( SIZE_MAX - count < namelen )
return errno = EOVERFLOW, -1;
struct fsm_req_tcsetblob msg;
struct fsm_resp_tcsetblob resp;
msg.ino = ino;
msg.namelen = namelen;
msg.count = count;
if ( SendMessage(channel, FSM_REQ_TCSETBLOB, &msg, sizeof(msg), namelen + count) &&
channel->KernelSend(&kctx, name, namelen) &&
channel->KernelSend(ctx, buffer, count) &&
RecvMessage(channel, FSM_RESP_TCSETBLOB, &resp, sizeof(resp)) )
ret = (ssize_t) resp.count;
channel->KernelClose();
return ret;
}
//
// Initialization.
//

View File

@ -100,6 +100,8 @@ public:
void* option_value, size_t* option_size_ptr);
int setsockopt(ioctx_t* ctx, int level, int option_name,
const void* option_value, size_t option_size);
ssize_t tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count);
ssize_t tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count);
private:
Ref<Descriptor> open_elem(ioctx_t* ctx, const char* filename, int flags,

View File

@ -110,6 +110,8 @@ public:
void* option_value, size_t* option_size_ptr) = 0;
virtual int setsockopt(ioctx_t* ctx, int level, int option_name,
const void* option_value, size_t option_size) = 0;
virtual ssize_t tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count) = 0;
virtual ssize_t tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count) = 0;
};
@ -194,6 +196,8 @@ public:
void* option_value, size_t* option_size_ptr);
virtual int setsockopt(ioctx_t* ctx, int level, int option_name,
const void* option_value, size_t option_size);
virtual ssize_t tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count);
virtual ssize_t tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count);
};

View File

@ -100,6 +100,8 @@ public:
void* option_value, size_t* option_size_ptr);
int setsockopt(ioctx_t* ctx, int level, int option_name,
const void* option_value, size_t option_size);
ssize_t tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count);
ssize_t tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count);
public /*TODO: private*/:
Ref<Inode> inode;

View File

@ -167,6 +167,8 @@
#define SYSCALL_RECVMSG 139
#define SYSCALL_GETSOCKOPT 140
#define SYSCALL_SETSOCKOPT 141
#define SYSCALL_MAX_NUM 142 /* index of highest constant + 1 */
#define SYSCALL_TCGETBLOB 142
#define SYSCALL_TCSETBLOB 143
#define SYSCALL_MAX_NUM 144 /* index of highest constant + 1 */
#endif

View File

@ -396,4 +396,14 @@ int AbstractInode::setsockopt(ioctx_t* /*ctx*/, int /*level*/, int /*option_name
return errno = ENOTSOCK, -1;
}
ssize_t AbstractInode::tcgetblob(ioctx_t* /*ctx*/, const char* /*name*/, void* /*buffer*/, size_t /*count*/)
{
return errno = ENOTTY, -1;
}
ssize_t AbstractInode::tcsetblob(ioctx_t* /*ctx*/, const char* /*name*/, const void* /*buffer*/, size_t /*count*/)
{
return errno = ENOTTY, -1;
}
} // namespace Sortix

View File

@ -1032,6 +1032,38 @@ static int sys_setsockopt(int fd, int level, int option_name,
return desc->setsockopt(&ctx, level, option_name, option_value, option_size);
}
static ssize_t sys_tcgetblob(int fd, const char* name, void* buffer, size_t count)
{
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
if ( !desc )
return -1;
char* name_copy = NULL;
if ( name && !(name_copy = GetStringFromUser(name)) )
return -1;
ioctx_t ctx; SetupUserIOCtx(&ctx);
ssize_t result = desc->tcgetblob(&ctx, name_copy, buffer, count);
delete[] name_copy;
return result;
}
static ssize_t sys_tcsetblob(int fd, const char* name, const void* buffer, size_t count)
{
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
if ( !desc )
return -1;
char* name_copy = NULL;
if ( name && !(name_copy = GetStringFromUser(name)) )
return -1;
ioctx_t ctx; SetupUserIOCtx(&ctx);
ssize_t result = desc->tcsetblob(&ctx, name_copy, buffer, count);
delete[] name_copy;
return result;
}
void Init()
{
Syscall::Register(SYSCALL_ACCEPT4, (void*) sys_accept4);
@ -1084,9 +1116,11 @@ void Init()
Syscall::Register(SYSCALL_SETSOCKOPT, (void*) sys_setsockopt);
Syscall::Register(SYSCALL_SETTERMMODE, (void*) sys_settermmode);
Syscall::Register(SYSCALL_SYMLINKAT, (void*) sys_symlinkat);
Syscall::Register(SYSCALL_TCGETBLOB, (void*) sys_tcgetblob);
Syscall::Register(SYSCALL_TCGETPGRP, (void*) sys_tcgetpgrp);
Syscall::Register(SYSCALL_TCGETWINCURPOS, (void*) sys_tcgetwincurpos);
Syscall::Register(SYSCALL_TCGETWINSIZE, (void*) sys_tcgetwinsize);
Syscall::Register(SYSCALL_TCSETBLOB, (void*) sys_tcsetblob);
Syscall::Register(SYSCALL_TCSETPGRP, (void*) sys_tcsetpgrp);
Syscall::Register(SYSCALL_TRUNCATEAT, (void*) sys_truncateat);
Syscall::Register(SYSCALL_UNLINKAT, (void*) sys_unlinkat);

View File

@ -444,4 +444,29 @@ int LogTerminal::poll(ioctx_t* /*ctx*/, PollNode* node)
return errno = EAGAIN, -1;
}
ssize_t LogTerminal::tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count)
{
if ( !name )
{
char index[] = "";
if ( buffer && count < sizeof(index) )
return errno = ERANGE, -1;
if ( buffer && !ctx->copy_to_dest(buffer, &index, sizeof(index)) )
return -1;
return (ssize_t) sizeof(index);
}
else
return errno = ENOENT, -1;
}
ssize_t LogTerminal::tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count)
{
(void) ctx;
(void) buffer;
(void) count;
if ( !name )
return errno = EPERM, -1;
else
return errno = ENOENT, -1;
}
} // namespace Sortix

View File

@ -51,6 +51,9 @@ public:
virtual int settermmode(ioctx_t* ctx, unsigned termmode);
virtual int gettermmode(ioctx_t* ctx, unsigned* termmode);
virtual int poll(ioctx_t* ctx, PollNode* node);
virtual ssize_t tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count);
virtual ssize_t tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count);
public:
virtual void OnKeystroke(Keyboard* keyboard, void* user);

View File

@ -306,4 +306,14 @@ int Vnode::setsockopt(ioctx_t* ctx, int level, int option_name,
return inode->setsockopt(ctx, level, option_name, option_value, option_size);
}
ssize_t Vnode::tcgetblob(ioctx_t* ctx, const char* name, void* buffer, size_t count)
{
return inode->tcgetblob(ctx, name, buffer, count);
}
ssize_t Vnode::tcsetblob(ioctx_t* ctx, const char* name, const void* buffer, size_t count)
{
return inode->tcsetblob(ctx, name, buffer, count);
}
} // namespace Sortix

View File

@ -511,8 +511,10 @@ sys/uio/writev.o \
sys/utsname/uname.o \
sys/wait/wait.o \
sys/wait/waitpid.o \
termios/tcgetblob.o \
termios/tcgetwincurpos.o \
termios/tcgetwinsize.o \
termios/tcsetblob.o \
time/clock_getres.o \
time/clock_gettime.o \
time/clock_gettimeres.o \

View File

@ -394,7 +394,38 @@ struct fsm_resp_getsockopt
/*uint8_t option[option_size];*/
};
#define FSM_MSG_NUM 49
#define FSM_REQ_TCGETBLOB 49
struct fsm_req_tcgetblob
{
ino_t ino;
size_t namelen;
/*char name[namelen];*/
};
#define FSM_RESP_TCGETBLOB 50
struct fsm_resp_tcgetblob
{
size_t count;
/*uint8_t data[count];*/
};
#define FSM_REQ_TCSETBLOB 51
struct fsm_req_tcsetblob
{
ino_t ino;
size_t namelen;
size_t count;
/*char name[namelen];*/
/*uint8_t data[count];*/
};
#define FSM_RESP_TCSETBLOB 52
struct fsm_resp_tcsetblob
{
size_t count;
};
#define FSM_MSG_NUM 53
#if defined(__cplusplus)
} /* extern "C" */

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014.
This file is part of the Sortix C Library.
@ -29,12 +29,21 @@
#include <sys/cdefs.h>
#include <sys/__/types.h>
#include <stddef.h>
#include <sortix/termios.h>
__BEGIN_DECLS
#ifndef __ssize_t_defined
#define __ssize_t_defined
typedef __ssize_t ssize_t;
#endif
ssize_t tcgetblob(int fd, const char* name, void* buffer, size_t count);
ssize_t tcsetblob(int fd, const char* name, const void* buffer, size_t count);
int tcgetwincurpos(int fd, struct wincurpos* wcp);
int tcgetwinsize(int fd, struct winsize* ws);

View File

@ -0,0 +1,34 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2014.
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/tcgetblob.cpp
Download a blob from a terminal.
*******************************************************************************/
#include <sys/syscall.h>
#include <termios.h>
DEFN_SYSCALL4(int, sys_tcgetblob, SYSCALL_TCGETBLOB, int, const char*, void*, size_t);
extern "C" ssize_t tcgetblob(int fd, const char* name, void* buffer, size_t count)
{
return sys_tcgetblob(fd, name, buffer, count);
}

View File

@ -0,0 +1,34 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2014.
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/tcsetblob.cpp
Upload a blob to a terminal.
*******************************************************************************/
#include <sys/syscall.h>
#include <termios.h>
DEFN_SYSCALL4(int, sys_tcsetblob, SYSCALL_TCSETBLOB, int, const char*, const void*, size_t);
extern "C" ssize_t tcsetblob(int fd, const char* name, const void* buffer, size_t count)
{
return sys_tcsetblob(fd, name, buffer, count);
}