mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
libc: split ioctl method
Use one ioctl method for each type of I/O control because by now the general method will become increasingly long. Fixes #3890.
This commit is contained in:
parent
1a54ee895e
commit
f3268cade6
@ -93,6 +93,22 @@ class Libc::Vfs_plugin : public Plugin
|
||||
|
||||
int _legacy_ioctl(File_descriptor *, unsigned long, char *);
|
||||
|
||||
struct Ioctl_result
|
||||
{
|
||||
bool handled;
|
||||
int error;
|
||||
};
|
||||
|
||||
/**
|
||||
* Terminal related I/O controls
|
||||
*/
|
||||
Ioctl_result _ioctl_tio(File_descriptor *, unsigned long, char *);
|
||||
|
||||
/**
|
||||
* Block related I/O controls
|
||||
*/
|
||||
Ioctl_result _ioctl_dio(File_descriptor *, unsigned long, char *);
|
||||
|
||||
/**
|
||||
* Call functor 'fn' with ioctl info for the given file descriptor 'fd'
|
||||
*
|
||||
|
@ -1061,15 +1061,16 @@ ssize_t Libc::Vfs_plugin::getdirentries(File_descriptor *fd, char *buf,
|
||||
}
|
||||
|
||||
|
||||
int Libc::Vfs_plugin::ioctl(File_descriptor *fd, unsigned long request, char *argp)
|
||||
Libc::Vfs_plugin::Ioctl_result
|
||||
Libc::Vfs_plugin::_ioctl_tio(File_descriptor *fd, unsigned long request, char *argp)
|
||||
{
|
||||
if (!argp)
|
||||
return { true, EINVAL };
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (request == TIOCGWINSZ) {
|
||||
|
||||
if (!argp)
|
||||
return Errno(EINVAL);
|
||||
|
||||
monitor().monitor([&] {
|
||||
_with_info(*fd, [&] (Xml_node info) {
|
||||
if (info.type() == "terminal") {
|
||||
@ -1098,12 +1099,25 @@ int Libc::Vfs_plugin::ioctl(File_descriptor *fd, unsigned long request, char *ar
|
||||
::memset(termios->c_cc, _POSIX_VDISABLE, sizeof(termios->c_cc));
|
||||
termios->c_ispeed = 0;
|
||||
termios->c_ospeed = 0;
|
||||
|
||||
handled = true;
|
||||
}
|
||||
|
||||
} else if (request == DIOCGMEDIASIZE) {
|
||||
return { handled, 0 };
|
||||
}
|
||||
|
||||
if (!argp)
|
||||
return Errno(EINVAL);
|
||||
|
||||
Libc::Vfs_plugin::Ioctl_result
|
||||
Libc::Vfs_plugin::_ioctl_dio(File_descriptor *fd, unsigned long request, char *argp)
|
||||
{
|
||||
if (!argp)
|
||||
return { true, EINVAL };
|
||||
|
||||
bool handled = false;
|
||||
|
||||
using ::off_t;
|
||||
|
||||
if (request == DIOCGMEDIASIZE) {
|
||||
|
||||
monitor().monitor([&] {
|
||||
_with_info(*fd, [&] (Xml_node info) {
|
||||
@ -1121,9 +1135,6 @@ int Libc::Vfs_plugin::ioctl(File_descriptor *fd, unsigned long request, char *ar
|
||||
warning("block count is 0");
|
||||
}
|
||||
|
||||
/* we need libc's off_t which is int64_t */
|
||||
using ::off_t;
|
||||
|
||||
off_t disk_size = (off_t) count * size;
|
||||
if (disk_size < 0) {
|
||||
warning("disk size overflow - returning 0");
|
||||
@ -1137,10 +1148,35 @@ int Libc::Vfs_plugin::ioctl(File_descriptor *fd, unsigned long request, char *ar
|
||||
|
||||
return Fn::COMPLETE;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (handled)
|
||||
return 0;
|
||||
return { handled, 0 };
|
||||
}
|
||||
|
||||
|
||||
int Libc::Vfs_plugin::ioctl(File_descriptor *fd, unsigned long request, char *argp)
|
||||
{
|
||||
Ioctl_result result { false, 0 };
|
||||
|
||||
/* we need libc's off_t which is int64_t */
|
||||
using ::off_t;
|
||||
|
||||
switch (request) {
|
||||
case TIOCGWINSZ:
|
||||
case TIOCGETA:
|
||||
result = _ioctl_tio(fd, request, argp);
|
||||
break;
|
||||
case DIOCGMEDIASIZE:
|
||||
result = _ioctl_dio(fd, request, argp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result.handled) {
|
||||
return result.error ? Errno(result.error) : 0;
|
||||
}
|
||||
|
||||
return _legacy_ioctl(fd, request, argp);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user