LxIP "peek" file

Add a control file for peeking at socket buffers.

Ref #2875
This commit is contained in:
Ehmry - 2018-06-21 09:34:11 +02:00 committed by Norman Feske
parent f1427fc02a
commit 7f928a6573
1 changed files with 59 additions and 1 deletions

View File

@ -129,6 +129,7 @@ namespace Vfs {
class Lxip_listen_file;
class Lxip_local_file;
class Lxip_remote_file;
class Lxip_peek_file;
class Lxip_socket_dir;
struct Lxip_socket_handle;
@ -521,6 +522,52 @@ class Vfs::Lxip_data_file final : public Vfs::Lxip_file
};
class Vfs::Lxip_peek_file final : public Vfs::Lxip_file
{
public:
Lxip_peek_file(Lxip::Socket_dir &p, Linux::socket &s)
: Lxip_file(p, s, "peek") { }
/********************
** File interface **
********************/
bool poll() override
{
/* can always peek */
return true;
}
Lxip::ssize_t write(Lxip_vfs_file_handle&,
char const *, Genode::size_t,
file_size) override
{
return -1;
}
Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len,
file_size /* ignored */) override
{
using namespace Linux;
if (!_sock_valid()) return -1;
iovec iov { dst, len };
msghdr msg = create_msghdr(nullptr, 0, len, &iov);
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, len, MSG_DONTWAIT|MSG_PEEK);
if (ret == -EAGAIN)
return 0;
return ret;
}
};
class Vfs::Lxip_bind_file final : public Vfs::Lxip_file
{
private:
@ -939,7 +986,8 @@ class Vfs::Lxip_socket_dir final : public Lxip::Socket_dir
enum {
ACCEPT_NODE, BIND_NODE, CONNECT_NODE,
DATA_NODE, LOCAL_NODE, LISTEN_NODE, REMOTE_NODE,
DATA_NODE, PEEK_NODE,
LOCAL_NODE, LISTEN_NODE, REMOTE_NODE,
ACCEPT_SOCKET_NODE,
MAX_FILES
};
@ -965,6 +1013,7 @@ class Vfs::Lxip_socket_dir final : public Lxip::Socket_dir
Lxip_bind_file _bind_file { *this, _sock };
Lxip_connect_file _connect_file { *this, _sock };
Lxip_data_file _data_file { *this, _sock };
Lxip_peek_file _peek_file { *this, _sock };
Lxip_listen_file _listen_file { *this, _sock };
Lxip_local_file _local_file { *this, _sock };
Lxip_remote_file _remote_file { *this, _sock };
@ -1001,6 +1050,7 @@ class Vfs::Lxip_socket_dir final : public Lxip::Socket_dir
_files[BIND_NODE] = &_bind_file;
_files[CONNECT_NODE] = &_connect_file;
_files[DATA_NODE] = &_data_file;
_files[PEEK_NODE] = &_peek_file;
_files[LOCAL_NODE] = &_local_file;
_files[REMOTE_NODE] = &_remote_file;
}
@ -1011,6 +1061,7 @@ class Vfs::Lxip_socket_dir final : public Lxip::Socket_dir
_bind_file.dissolve_handles();
_connect_file.dissolve_handles();
_data_file.dissolve_handles();
_peek_file.dissolve_handles();
_listen_file.dissolve_handles();
_local_file.dissolve_handles();
_remote_file.dissolve_handles();
@ -1781,6 +1832,13 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
return STAT_OK;
}
if (dynamic_cast<Lxip_peek_file*>(node)) {
out.type = Node_type::CONTINUOUS_FILE;
out.rwx = Node_rwx::rw();
out.size = 0;
return STAT_OK;
}
if (dynamic_cast<Vfs::File*>(node)) {
out.type = Node_type::TRANSACTIONAL_FILE;
out.rwx = Node_rwx::rw();