Skip to content

Instantly share code, notes, and snippets.

@dragonmux
Last active August 31, 2017 21:37
Show Gist options
  • Save dragonmux/819fe316c44de8232503477fa02f486d to your computer and use it in GitHub Desktop.
Save dragonmux/819fe316c44de8232503477fa02f486d to your computer and use it in GitHub Desktop.
Pipe type
#ifndef PIPE__HXX
#define PIPE__HXX
#include <unistd.h>
#include <fcntl.h>
#include "fd.hxx"
bool cloexec(fd_t fd) noexcept
{
if (!fd.valid())
return false;
int32_t flags;
flags = fcntl(fd, F_GETFD);
if (flags < 0)
return false;
return fcntl(fd, F_SETFD, flags | O_CLOEXEC) != -1;
}
struct pipe_t final
{
private:
fd_t readFD;
fd_t writeFD;
public:
pipe_t() noexcept : readFD(), writeFD()
{
int32_t pipeFDs[2];
if (pipe(pipeFDs) != 0)
return;
readFD = pipeFDs[0];
writeFD = pipeFDs[1];
}
pipe_t(pipe_t &&pipe) noexcept : readFD(), writeFD() { swap(pipe); }
void operator =(pipe_t &&pipe) noexcept { swap(pipe); }
// We are valid if at least one of our ends is.
bool valid() const noexcept { return readFD.valid() || writeFD.valid(); }
// Need templates for these.. but they're copy-pasta from the fd_t type.
bool read(void *const value, const size_t valueLen) const noexcept WARN_UNUSED
{
if (!readFD.valid())
return false;
return readFD.read(value, valueLen);
}
ssize_t write(const void *const value, const size_t valueLen) const noexcept
{
if (!writeFD.valid())
return -1;
return writeFD.write(value, valueLen);
}
void closeRead() noexcept { readFD = fd_t(); }
void closeWrite() noexcept { writeFD = fd_t(); }
bool cloexecRead() noexcept { return cloexec(readFD); }
bool cloexecWrite() noexcept { return cloexec(writeFD); }
void swap(pipe_t &pipe) noexcept
{
readFD.swap(pipe.readFD);
writeFD.swap(pipe.writeFD);
}
pipe_t(const pipe_t &) = delete;
pipe_t &operator =(const pipe_t &) = delete;
};
void swap(pipe_t &a, pipe_t &b) noexcept
{ a.swap(b); }
#endif /*PIPE__HXX*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment