/* * \brief Client-side Terminal session interface * \author Norman Feske * \date 2011-08-11 */ /* * Copyright (C) 2011-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. */ #ifndef _INCLUDE__TERMINAL_SESSION__CLIENT_H_ #define _INCLUDE__TERMINAL_SESSION__CLIENT_H_ /* Genode includes */ #include #include #include #include #include #include namespace Terminal { class Session_client; } class Terminal::Session_client : public Genode::Rpc_client { private: Genode::Mutex _mutex { }; /** * Shared-memory buffer used for carrying the payload * of read/write operations */ Genode::Attached_dataspace _io_buffer; public: Session_client(Genode::Region_map &local_rm, Genode::Capability cap) : Genode::Rpc_client(cap), _io_buffer(local_rm, call()) { } Size size() override { return call(); } bool avail() override { return call(); } Genode::size_t read(void *buf, Genode::size_t buf_size) override { Genode::Mutex::Guard _guard(_mutex); /* instruct server to fill the I/O buffer */ Genode::size_t num_bytes = call(buf_size); /* copy-out I/O buffer */ num_bytes = Genode::min(num_bytes, buf_size); Genode::memcpy(buf, _io_buffer.local_addr(), num_bytes); return num_bytes; } Genode::size_t write(void const *buf, Genode::size_t num_bytes) override { Genode::Mutex::Guard _guard(_mutex); Genode::size_t written_bytes = 0; char const * const src = (char const *)buf; while (written_bytes < num_bytes) { /* copy payload to I/O buffer */ Genode::size_t payload_bytes = Genode::min(num_bytes - written_bytes, _io_buffer.size()); Genode::memcpy(_io_buffer.local_addr(), src + written_bytes, payload_bytes); /* tell server to pick up new I/O buffer content */ Genode::size_t written_payload_bytes = call(payload_bytes); written_bytes += written_payload_bytes; if (written_payload_bytes != payload_bytes) return written_bytes; } return written_bytes; } void connected_sigh(Genode::Signal_context_capability cap) override { call(cap); } void read_avail_sigh(Genode::Signal_context_capability cap) override { call(cap); } void size_changed_sigh(Genode::Signal_context_capability cap) override { call(cap); } Genode::size_t io_buffer_size() const { return _io_buffer.size(); } }; #endif /* _INCLUDE__TERMINAL_SESSION__CLIENT_H_ */