Ensure we don't leak half of a pipe

It was possible though unlikely for make_autoclose_pipes to close only
one side of pipe, if it fails to find a new fd. This would result in an
fd leak. Ensure that doesn't happen.
This commit is contained in:
ridiculousfish 2020-09-05 13:24:26 -07:00
parent 1cef87d790
commit d1dab22691
2 changed files with 12 additions and 5 deletions

View File

@ -327,13 +327,18 @@ maybe_t<autoclose_pipes_t> make_autoclose_pipes(const fd_set_t &fdset) {
set_cloexec(pipes[0]);
set_cloexec(pipes[1]);
auto read = move_fd_to_unused(autoclose_fd_t{pipes[0]}, fdset);
if (!read.valid()) return none();
autoclose_fd_t read_end{pipes[0]};
autoclose_fd_t write_end{pipes[1]};
auto write = move_fd_to_unused(autoclose_fd_t{pipes[1]}, fdset);
if (!write.valid()) return none();
// Ensure we have no conflicts.
if (!fdset.empty()) {
read_end = move_fd_to_unused(std::move(read_end), fdset);
if (!read_end.valid()) return none();
return autoclose_pipes_t(std::move(read), std::move(write));
write_end = move_fd_to_unused(std::move(write_end), fdset);
if (!write_end.valid()) return none();
}
return autoclose_pipes_t(std::move(read_end), std::move(write_end));
}
shared_ptr<const io_data_t> io_chain_t::io_for_fd(int fd) const {

View File

@ -39,6 +39,8 @@ struct fd_set_t {
assert(fd >= 0 && "Invalid fd");
return static_cast<size_t>(fd) < fds.size() && fds[fd];
}
bool empty() const { return fds.empty(); }
};
/// separated_buffer_t is composed of a sequence of elements, some of which may be explicitly