CernVM-FS  2.12.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() {
74  Close();
75  }
76 
80  void Close() {
81  CloseReadFd();
82  CloseWriteFd();
83  }
84 
88  void CloseReadFd() {
89  if (fd_read_ >= 0) {
90  close(fd_read_);
91  fd_read_ = -1;
92  }
93  }
94 
98  void CloseWriteFd() {
99  if (fd_write_ >= 0) {
100  close(fd_write_);
101  fd_write_ = -1;
102  }
103  }
104 
111  template<typename T>
112  bool TryWrite(const T &data) {
113  const int num_bytes = write(fd_write_, &data, sizeof(T));
114  return (num_bytes >= 0) && (static_cast<size_t>(num_bytes) == sizeof(T));
115  }
116 
124  template<typename T>
125  bool Write(const T &data) {
126  WritePipe(fd_write_, &data, sizeof(T));
127  return true;
128  }
129 
138  bool Write(const void *buf, size_t nbyte) {
139  WritePipe(fd_write_, buf, nbyte);
140  return true;
141  }
142 
150  template<typename T>
151  bool TryRead(T *data) {
152  ssize_t num_bytes;
153  do {
154  num_bytes = read(fd_read_, data, sizeof(T));
155  } while ((num_bytes < 0) && (errno == EINTR));
156  return (num_bytes >= 0) && (static_cast<size_t>(num_bytes) == sizeof(T));
157  }
158 
165  template<typename T>
166  bool Read(T *data) {
167  ReadPipe(fd_read_, data, sizeof(T));
168  return true;
169  }
170 
178  bool Read(void *buf, size_t nbyte) {
179  ReadPipe(fd_read_, buf, nbyte);
180  return true;
181  }
182 
186  int GetReadFd() const {
187  return fd_read_;
188  }
189 
193  int GetWriteFd() const {
194  return fd_write_;
195  }
196 
197 
198  private:
199  int fd_read_;
201 
205  Pipe(const int fd_read, const int fd_write) : fd_read_(fd_read),
206  fd_write_(fd_write) {}
207 
211  void MakePipe(int pipe_fd[2]) {
212  int retval = pipe(pipe_fd);
213  if (retval != 0) {
214  PANIC(kLogSyslogErr | kLogDebug, "MakePipe failed with errno %d", errno);
215  }
216  }
217 
218 
222  void WritePipe(int fd, const void *buf, size_t nbyte) {
223  ssize_t num_bytes;
224  do {
225  num_bytes = write(fd, buf, nbyte);
226  } while ((num_bytes < 0) && (errno == EINTR));
227  if (!((num_bytes >= 0) && (static_cast<size_t>(num_bytes) == nbyte))) {
229  "WritePipe failed: expected write size %lu, "
230  "actually written %lu, errno %d, fd %d",
231  nbyte, num_bytes, errno, fd);
232  }
233  }
234 
235 
239  void ReadPipe(int fd, void *buf, size_t nbyte) {
240  ssize_t num_bytes;
241  do {
242  num_bytes = read(fd, buf, nbyte);
243  } while ((num_bytes < 0) && (errno == EINTR));
244  if (!((num_bytes >= 0) && (static_cast<size_t>(num_bytes) == nbyte))) {
246  "ReadPipe failed: expected read size %lu, "
247  "actually read %lu, errno %d, fd %d",
248  nbyte, num_bytes, errno, fd);
249  }
250  }
251 };
252 
253 #ifdef CVMFS_NAMESPACE_GUARD
254 } // namespace CVMFS_NAMESPACE_GUARD
255 #endif
256 
257 #endif // CVMFS_UTIL_PIPE_H_
int GetReadFd() const
Definition: pipe.h:186
void CloseReadFd()
Definition: pipe.h:88
bool Write(const T &data)
Definition: pipe.h:125
#define PANIC(...)
Definition: exception.h:29
PipeType
Definition: pipe.h:26
#define CVMFS_EXPORT
Definition: export.h:11
void CloseWriteFd()
Definition: pipe.h:98
int fd_read_
Definition: pipe.h:199
PipeSignals
Definition: pipe.h:40
int GetWriteFd() const
Definition: pipe.h:193
~Pipe()
Definition: pipe.h:73
void MakePipe(int pipe_fd[2])
Definition: posix.cc:492
Definition: pipe.h:45
Pipe()
Definition: pipe.h:63
Definition: pipe.h:32
bool Read(void *buf, size_t nbyte)
Definition: pipe.h:178
void WritePipe(int fd, const void *buf, size_t nbyte)
Definition: pipe.h:222
void ReadPipe(int fd, void *buf, size_t nbyte)
Definition: pipe.h:239
bool Read(T *data)
Definition: pipe.h:166
bool Write(const void *buf, size_t nbyte)
Definition: pipe.h:138
void Close()
Definition: pipe.h:80
bool TryRead(T *data)
Definition: pipe.h:151
Pipe(const int fd_read, const int fd_write)
Definition: pipe.h:205
void MakePipe(int pipe_fd[2])
Definition: pipe.h:211
int fd_write_
Definition: pipe.h:200
void WritePipe(int fd, const void *buf, size_t nbyte)
Definition: posix.cc:501
void ReadPipe(int fd, void *buf, size_t nbyte)
Definition: posix.cc:513
bool TryWrite(const T &data)
Definition: pipe.h:112