vfs: remove File_io_service::ioctl interface

This interface has been obsoleted by the use of pseudo files,
implemented in the context of issue #3519.

Issue #4706
This commit is contained in:
Norman Feske 2022-12-19 16:08:20 +01:00 committed by Christian Helmuth
parent 08c56e61e1
commit 0fefee804c
3 changed files with 3 additions and 194 deletions

View File

@ -103,8 +103,6 @@ class Libc::Vfs_plugin final : public Plugin
*/
void _vfs_write_mtime(Vfs::Vfs_handle&);
int _legacy_ioctl(File_descriptor *, unsigned long, char *);
struct Ioctl_result
{
bool handled;

View File

@ -1941,157 +1941,10 @@ int Libc::Vfs_plugin::ioctl(File_descriptor *fd, unsigned long request, char *ar
break;
}
if (result.handled)
return result.error ? Errno(result.error) : 0;
if (!result.handled)
return Errno(EINVAL);
return _legacy_ioctl(fd, request, argp);
}
/**
* Fallback for ioctl operations targeting the deprecated VFS ioctl interface
*
* XXX Remove this method once all ioctl operations are supported via
* regular VFS file accesses.
*/
int Libc::Vfs_plugin::_legacy_ioctl(File_descriptor *fd, unsigned long request, char *argp)
{
using ::off_t;
/*
* Marshal ioctl arguments
*/
typedef Vfs::File_io_service::Ioctl_opcode Opcode;
Opcode opcode = Opcode::IOCTL_OP_UNDEFINED;
Vfs::File_io_service::Ioctl_arg arg = 0;
switch (request) {
case TIOCGWINSZ:
{
if (!argp) {
errno = EINVAL;
return -1;
}
opcode = Opcode::IOCTL_OP_TIOCGWINSZ;
break;
}
case TIOCSETAF:
{
opcode = Opcode::IOCTL_OP_TIOCSETAF;
::termios *termios = (::termios *)argp;
/*
* For now only enabling/disabling of ECHO is supported
*/
if (termios->c_lflag & (ECHO | ECHONL)) {
arg = (Vfs::File_io_service::IOCTL_VAL_ECHO |
Vfs::File_io_service::IOCTL_VAL_ECHONL);
}
else {
arg = Vfs::File_io_service::IOCTL_VAL_NULL;
}
break;
}
case TIOCSETAW:
{
opcode = Opcode::IOCTL_OP_TIOCSETAW;
arg = argp ? *(int*)argp : 0;
break;
}
case FIONBIO:
{
opcode = Opcode::IOCTL_OP_FIONBIO;
arg = argp ? *(int*)argp : 0;
break;
}
case DIOCGMEDIASIZE:
{
if (!argp) {
errno = EINVAL;
return -1;
}
opcode = Opcode::IOCTL_OP_DIOCGMEDIASIZE;
arg = 0;
break;
}
default:
warning("unsupported ioctl (request=", Hex(request), ")");
break;
}
if (opcode == Opcode::IOCTL_OP_UNDEFINED) {
errno = ENOTTY;
return -1;
}
typedef Vfs::File_io_service::Ioctl_result Result;
Vfs::File_io_service::Ioctl_out out;
Genode::memset(&out, 0, sizeof(out));
Vfs::Vfs_handle *handle = vfs_handle(fd);
bool succeeded = false;
int result_errno = 0;
monitor().monitor([&] {
switch (handle->fs().ioctl(handle, opcode, arg, out)) {
case Result::IOCTL_ERR_INVALID: result_errno = EINVAL; break;
case Result::IOCTL_ERR_NOTTY: result_errno = ENOTTY; break;
case Result::IOCTL_OK: succeeded = true; break;
}
return Fn::COMPLETE;
});
if (!succeeded)
return Errno(result_errno);
/*
* Unmarshal ioctl results
*/
switch (request) {
case TIOCGWINSZ:
{
::winsize *winsize = (::winsize *)argp;
winsize->ws_row = out.tiocgwinsz.rows;
winsize->ws_col = out.tiocgwinsz.columns;
return 0;
}
case TIOCSETAF:
case TIOCSETAW:
return 0;
case FIONBIO:
return 0;
case DIOCGMEDIASIZE:
{
/* resolve ambiguity with libc type */
using Genode::int64_t;
int64_t *disk_size = (int64_t*)argp;
*disk_size = out.diocgmediasize.size;
return 0;
}
default:
break;
}
return -1;
return result.error ? Errno(result.error) : 0;
}

View File

@ -96,48 +96,6 @@ struct Vfs::File_io_service : Interface
virtual Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size len) = 0;
/***********
** Ioctl **
***********/
enum Ioctl_result { IOCTL_ERR_INVALID, IOCTL_ERR_NOTTY, IOCTL_OK };
enum Ioctl_opcode { IOCTL_OP_UNDEFINED, IOCTL_OP_TIOCGWINSZ,
IOCTL_OP_TIOCSETAF, IOCTL_OP_TIOCSETAW,
IOCTL_OP_FIONBIO, IOCTL_OP_DIOCGMEDIASIZE };
enum Ioctl_value { IOCTL_VAL_NULL, IOCTL_VAL_ECHO, IOCTL_VAL_ECHONL };
typedef unsigned long Ioctl_arg;
struct Ioctl_out
{
union
{
/* if request was 'IOCTL_OP_TIOCGWINSZ' */
struct {
int rows;
int columns;
} tiocgwinsz;
/* if request was 'IOCTL_OP_DIOCGMEDIASIZE' */
struct {
/* disk size rounded up to sector size in bytes*/
file_size size;
} diocgmediasize;
};
};
virtual Ioctl_result ioctl(Vfs_handle *, Ioctl_opcode, Ioctl_arg, Ioctl_out &)
{
/*
* This method is only needed in file systems which actually implement a
* device and is therefore false by default.
*/
return IOCTL_ERR_INVALID;
}
virtual void register_read_ready_sigh(Vfs_handle *, Signal_context_capability)
{ }