mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Add tcgetblob(2) and tcsetblob(2).
This commit is contained in:
parent
d6067f9da7
commit
01402052f6
16 changed files with 276 additions and 3 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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" */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
34
libc/termios/tcgetblob.cpp
Normal file
34
libc/termios/tcgetblob.cpp
Normal 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);
|
||||
}
|
34
libc/termios/tcsetblob.cpp
Normal file
34
libc/termios/tcsetblob.cpp
Normal 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);
|
||||
}
|
Loading…
Add table
Reference in a new issue