CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pipe.h
Go to the documentation of this file.
1 
5 #ifndef CVMFS_UTIL_PIPE_H_
6 #define CVMFS_UTIL_PIPE_H_
7 
8 #include <sys/types.h>
9 #include <unistd.h>
10 
11 #include <cerrno>
12 
13 #include "exception.h"
14 #include "gtest/gtest_prod.h"
15 #include "util/export.h"
16 #include "util/single_copy.h"
17 
18 #ifdef CVMFS_NAMESPACE_GUARD
19 namespace CVMFS_NAMESPACE_GUARD {
20 #endif
21 
26 enum PipeType {
27  kPipeThreadTerminator = 0, // pipe only used to signal a thread to stop
35 };
36 
42 };
43 
44 template<PipeType pipeType>
45 class CVMFS_EXPORT Pipe : public SingleCopy {
46  FRIEND_TEST(T_Util, ManagedExecRunShell);
47  FRIEND_TEST(T_Util, ManagedExecExecuteBinaryDoubleFork);
48  FRIEND_TEST(T_Util, ManagedExecExecuteBinaryAsChild);
49 
50  public:
63  Pipe() {
64  int pipe_fd[2];
65  MakePipe(pipe_fd);
66  fd_read_ = pipe_fd[0];
67  fd_write_ = pipe_fd[1];
68  }
69 
73  ~Pipe() { Close(); }
74 
78  void Close() {
79  CloseReadFd();
80  CloseWriteFd();
81  }
82 
86  void CloseReadFd() {
87  if (fd_read_ >= 0) {
88  close(fd_read_);
89  fd_read_ = -1;
90  }
91  }
92 
96  void CloseWriteFd() {
97  if (fd_write_ >= 0) {
98  close(fd_write_);
99  fd_write_ = -1;
100  }
101  }
102 
109  template<typename T>
110  bool TryWrite(const T &data) {
111  const int num_bytes = write(fd_write_, &data, sizeof(T));
112  return (num_bytes >= 0) && (static_cast<size_t>(num_bytes) == sizeof(T));
113  }
114 
122  template<typename T>
123  bool Write(const T &data) {
124  WritePipe(fd_write_, &data, sizeof(T));
125  return true;
126  }
127 
136  bool Write(const void *buf, size_t nbyte) {
137  WritePipe(fd_write_, buf, nbyte);
138  return true;
139  }
140 
148  template<typename T>
149  bool TryRead(T *data) {
150  ssize_t num_bytes;
151  do {
152  num_bytes = read(fd_read_, data, sizeof(T));
153  } while ((num_bytes < 0) && (errno == EINTR));
154  return (num_bytes >= 0) && (static_cast<size_t>(num_bytes) == sizeof(T));
155  }
156 
163  template<typename T>
164  bool Read(T *data) {
165  ReadPipe(fd_read_, data, sizeof(T));
166  return true;
167  }
168 
176  bool Read(void *buf, size_t nbyte) {
177  ReadPipe(fd_read_, buf, nbyte);
178  return true;
179  }
180 
184  int GetReadFd() const { return fd_read_; }
185 
189  int GetWriteFd() const { return fd_write_; }
190 
191 
192  private:
193  int fd_read_;
195 
199  Pipe(const int fd_read, const int fd_write)
200  : fd_read_(fd_read), fd_write_(fd_write) { }
201 
205  void MakePipe(int pipe_fd[2]) {
206  const int retval = pipe(pipe_fd);
207  if (retval != 0) {
208  PANIC(kLogSyslogErr | kLogDebug, "MakePipe failed with errno %d", errno);
209  }
210  }
211 
212 
216  void WritePipe(int fd, const void *buf, size_t nbyte) {
217  ssize_t num_bytes;
218  do {
219  num_bytes = write(fd, buf, nbyte);
220  } while ((num_bytes < 0) && (errno == EINTR));
221  if (!((num_bytes >= 0) && (static_cast<size_t>(num_bytes) == nbyte))) {
223  "WritePipe failed: expected write size %lu, "
224  "actually written %lu, errno %d, fd %d",
225  nbyte, num_bytes, errno, fd);
226  }
227  }
228 
229 
233  void ReadPipe(int fd, void *buf, size_t nbyte) {
234  ssize_t num_bytes;
235  do {
236  num_bytes = read(fd, buf, nbyte);
237  } while ((num_bytes < 0) && (errno == EINTR));
238  if (!((num_bytes >= 0) && (static_cast<size_t>(num_bytes) == nbyte))) {
240  "ReadPipe failed: expected read size %lu, "
241  "actually read %lu, errno %d, fd %d",
242  nbyte, num_bytes, errno, fd);
243  }
244  }
245 };
246 
247 #ifdef CVMFS_NAMESPACE_GUARD
248 } // namespace CVMFS_NAMESPACE_GUARD
249 #endif
250 
251 #endif // CVMFS_UTIL_PIPE_H_
int GetReadFd() const
Definition: pipe.h:184
void CloseReadFd()
Definition: pipe.h:86
bool Write(const T &data)
Definition: pipe.h:123
#define PANIC(...)
Definition: exception.h:29
PipeType
Definition: pipe.h:26
#define CVMFS_EXPORT
Definition: export.h:11
void CloseWriteFd()
Definition: pipe.h:96
int fd_read_
Definition: pipe.h:193
PipeSignals
Definition: pipe.h:40
int GetWriteFd() const
Definition: pipe.h:189
~Pipe()
Definition: pipe.h:73
void MakePipe(int pipe_fd[2])
Definition: posix.cc:487
Definition: pipe.h:45
Pipe()
Definition: pipe.h:63
Definition: pipe.h:32
bool Read(void *buf, size_t nbyte)
Definition: pipe.h:176
void WritePipe(int fd, const void *buf, size_t nbyte)
Definition: pipe.h:216
void ReadPipe(int fd, void *buf, size_t nbyte)
Definition: pipe.h:233
bool Read(T *data)
Definition: pipe.h:164
bool Write(const void *buf, size_t nbyte)
Definition: pipe.h:136
void Close()
Definition: pipe.h:78
bool TryRead(T *data)
Definition: pipe.h:149
Pipe(const int fd_read, const int fd_write)
Definition: pipe.h:199
void MakePipe(int pipe_fd[2])
Definition: pipe.h:205
int fd_write_
Definition: pipe.h:194
void WritePipe(int fd, const void *buf, size_t nbyte)
Definition: posix.cc:496
void ReadPipe(int fd, void *buf, size_t nbyte)
Definition: posix.cc:508
bool TryWrite(const T &data)
Definition: pipe.h:110