From 7f928a6573654de060b9bdad1da09697b4212a25 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 21 Jun 2018 09:34:11 +0200 Subject: [PATCH] LxIP "peek" file Add a control file for peeking at socket buffers. Ref #2875 --- repos/dde_linux/src/lib/vfs/lxip/vfs.cc | 60 ++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/repos/dde_linux/src/lib/vfs/lxip/vfs.cc b/repos/dde_linux/src/lib/vfs/lxip/vfs.cc index 5af3632f8..f811bf473 100644 --- a/repos/dde_linux/src/lib/vfs/lxip/vfs.cc +++ b/repos/dde_linux/src/lib/vfs/lxip/vfs.cc @@ -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(node)) { + out.type = Node_type::CONTINUOUS_FILE; + out.rwx = Node_rwx::rw(); + out.size = 0; + return STAT_OK; + } + if (dynamic_cast(node)) { out.type = Node_type::TRANSACTIONAL_FILE; out.rwx = Node_rwx::rw();