From 739317a83f0b0b84e0205fc1999dae4df66f0e4f Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Mon, 29 Apr 2019 16:52:46 +0200 Subject: [PATCH] noux: support non-blocking pipes Needed for 'noux_gdb.run' with newer gdb versions. Fixes #3319 --- repos/ports/include/noux_session/sysio.h | 4 ++++ repos/ports/src/noux/pipe_io_channel.h | 20 ++++++++++++++++++++ repos/ports/src/noux/syscall.cc | 16 ++++++++++++---- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/repos/ports/include/noux_session/sysio.h b/repos/ports/include/noux_session/sysio.h index a8bd724e06..ae2edc605c 100644 --- a/repos/ports/include/noux_session/sysio.h +++ b/repos/ports/include/noux_session/sysio.h @@ -160,6 +160,10 @@ struct Noux::Sysio FCNTL_CMD_GET_FD_FLAGS }; + enum { + FCNTL_FILE_STATUS_FLAG_NONBLOCK = 4 + }; + /** * Input and output argument type of select syscall */ diff --git a/repos/ports/src/noux/pipe_io_channel.h b/repos/ports/src/noux/pipe_io_channel.h index efffb51040..662b3ffae2 100644 --- a/repos/ports/src/noux/pipe_io_channel.h +++ b/repos/ports/src/noux/pipe_io_channel.h @@ -222,6 +222,8 @@ class Noux::Pipe_sink_io_channel : public Io_channel Shared_pointer _pipe; + bool _nonblocking { false }; + public: Pipe_sink_io_channel(Shared_pointer pipe, Entrypoint &ep) @@ -239,6 +241,8 @@ class Noux::Pipe_sink_io_channel : public Io_channel return wr && _pipe->any_space_avail_for_writing(); } + bool nonblocking() override { return _nonblocking; } + bool write(Sysio &sysio) override { sysio.write_out.count = _pipe->write(sysio.write_in.chunk, @@ -254,6 +258,12 @@ class Noux::Pipe_sink_io_channel : public Io_channel sysio.fcntl_out.result = Sysio::OPEN_MODE_WRONLY; return true; + case Sysio::FCNTL_CMD_SET_FILE_STATUS_FLAGS: + _nonblocking = (sysio.fcntl_in.long_arg & + Sysio::FCNTL_FILE_STATUS_FLAG_NONBLOCK); + sysio.fcntl_out.result = 0; + return true; + default: return false; } @@ -277,6 +287,8 @@ class Noux::Pipe_source_io_channel : public Io_channel Shared_pointer _pipe; + bool _nonblocking { false }; + public: Pipe_source_io_channel(Shared_pointer pipe, Entrypoint &ep) @@ -298,6 +310,8 @@ class Noux::Pipe_source_io_channel : public Io_channel return (rd && _pipe->data_avail_for_reading()); } + bool nonblocking() override { return _nonblocking; } + bool read(Sysio &sysio) override { size_t const max_count = @@ -318,6 +332,12 @@ class Noux::Pipe_source_io_channel : public Io_channel sysio.fcntl_out.result = Sysio::OPEN_MODE_RDONLY; return true; + case Sysio::FCNTL_CMD_SET_FILE_STATUS_FLAGS: + _nonblocking = (sysio.fcntl_in.long_arg & + Sysio::FCNTL_FILE_STATUS_FLAG_NONBLOCK); + sysio.fcntl_out.result = 0; + return true; + default: return false; } diff --git a/repos/ports/src/noux/syscall.cc b/repos/ports/src/noux/syscall.cc index 67251b9013..2cabfedafb 100644 --- a/repos/ports/src/noux/syscall.cc +++ b/repos/ports/src/noux/syscall.cc @@ -58,8 +58,12 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) if (io->check_unblock(false, true, false)) { /* 'io->write' is expected to update '_sysio.write_out.count' */ result = io->write(_sysio); - } else - _sysio.error.write = Vfs::File_io_service::WRITE_ERR_INTERRUPT; + } else { + if (io->nonblocking()) + _sysio.error.write = Vfs::File_io_service::WRITE_ERR_WOULD_BLOCK; + else + _sysio.error.write = Vfs::File_io_service::WRITE_ERR_INTERRUPT; + } break; } @@ -73,8 +77,12 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) if (io->check_unblock(true, false, false)) result = io->read(_sysio); - else - _sysio.error.read = Vfs::File_io_service::READ_ERR_INTERRUPT; + else { + if (io->nonblocking()) + _sysio.error.read = Vfs::File_io_service::READ_ERR_WOULD_BLOCK; + else + _sysio.error.read = Vfs::File_io_service::READ_ERR_INTERRUPT; + } break; }