noux: support non-blocking pipes

Needed for 'noux_gdb.run' with newer gdb versions.

Fixes #3319
This commit is contained in:
Christian Prochaska 2019-04-29 16:52:46 +02:00 committed by Christian Helmuth
parent 92510af9d4
commit 739317a83f
3 changed files with 36 additions and 4 deletions

View File

@ -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
*/

View File

@ -222,6 +222,8 @@ class Noux::Pipe_sink_io_channel : public Io_channel
Shared_pointer<Pipe> _pipe;
bool _nonblocking { false };
public:
Pipe_sink_io_channel(Shared_pointer<Pipe> 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> _pipe;
bool _nonblocking { false };
public:
Pipe_source_io_channel(Shared_pointer<Pipe> 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;
}

View File

@ -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;
}