mirror of
https://github.com/NixOS/nix.git
synced 2025-11-10 12:36:01 +01:00
This will facilitate breaking up Nix into multiple packages for each component with Meson.
47 lines
1.5 KiB
C++
47 lines
1.5 KiB
C++
#include <poll.h>
|
|
|
|
#include "logging.hh"
|
|
#include "util.hh"
|
|
#include "muxable-pipe.hh"
|
|
|
|
namespace nix {
|
|
|
|
void MuxablePipePollState::poll(std::optional<unsigned int> timeout)
|
|
{
|
|
if (::poll(pollStatus.data(), pollStatus.size(), timeout ? *timeout : -1) == -1) {
|
|
if (errno == EINTR)
|
|
return;
|
|
throw SysError("waiting for input");
|
|
}
|
|
}
|
|
|
|
void MuxablePipePollState::iterate(
|
|
std::set<MuxablePipePollState::CommChannel> & channels,
|
|
std::function<void(Descriptor fd, std::string_view data)> handleRead,
|
|
std::function<void(Descriptor fd)> handleEOF)
|
|
{
|
|
std::set<Descriptor> fds2(channels);
|
|
std::vector<unsigned char> buffer(4096);
|
|
for (auto & k : fds2) {
|
|
const auto fdPollStatusId = get(fdToPollStatus, k);
|
|
assert(fdPollStatusId);
|
|
assert(*fdPollStatusId < pollStatus.size());
|
|
if (pollStatus.at(*fdPollStatusId).revents) {
|
|
ssize_t rd = ::read(fromDescriptorReadOnly(k), buffer.data(), buffer.size());
|
|
// FIXME: is there a cleaner way to handle pt close
|
|
// than EIO? Is this even standard?
|
|
if (rd == 0 || (rd == -1 && errno == EIO)) {
|
|
handleEOF(k);
|
|
channels.erase(k);
|
|
} else if (rd == -1) {
|
|
if (errno != EINTR)
|
|
throw SysError("read failed");
|
|
} else {
|
|
std::string_view data((char *) buffer.data(), rd);
|
|
handleRead(k, data);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|