PlasCom2  1.0
XPACC Multi-physics simluation application
FDUtils.H
Go to the documentation of this file.
1 #include <sys/types.h>
7 #include <dirent.h>
8 #include <sys/stat.h>
9 #include <unistd.h>
10 #include <time.h>
11 #include <istream>
12 #include <ostream>
13 #include <streambuf>
14 #include <cstdio>
15 #include <cstring>
16 #include <sstream>
17 
18 //#include "primitive_utilities.H"
19 
20 namespace ix {
21 
22  namespace sys {
23 
24 
25  // Josuttis' fdstream classes (slightly modified)
26 
27  /************************************************************
28  * fdostream
29  * - a stream that writes on a file descriptor
30  ************************************************************/
31 
32 
33  class fdoutbuf : public std::streambuf {
34  protected:
35  int fd; // file descriptor
36  public:
37  fdoutbuf() { fd = -1; };
38  // constructor
39  fdoutbuf (int _fd) : fd(_fd) {
40  }
41  void Init(int _fd){ fd = _fd; };
42  bool Ready(){ return(fd >= 0); };
43  virtual int FD() { return fd; };
44  protected:
45  // write one character
46  virtual int_type overflow (int_type c) {
47  if (c != EOF) {
48  char z = c;
49  if (write (fd, &z, 1) != 1) {
50  return EOF;
51  }
52  }
53  return c;
54  }
55  // write multiple characters
56  virtual
57  std::streamsize xsputn (const char* s,
58  std::streamsize num) {
59  return write(fd,s,num);
60  }
61  };
62 
63  class fdostream : public std::ostream {
64  protected:
66  public:
67  fdostream () : std::ostream(0) {};
68  fdostream (int fd) : std::ostream(0), buf(fd) {
69  rdbuf(&buf);
70  }
71  int FD() { return(buf.FD()); };
72  int Init(int _fd) { buf.Init(_fd); rdbuf(&buf); return(buf.FD());};
73  };
74 
75 
76  /************************************************************
77  * fdistream
78  * - a stream that reads on a file descriptor
79  ************************************************************/
80 
81  class fdinbuf : public std::streambuf {
82  protected:
83  int fd; // file descriptor
84  protected:
85  /* data buffer:
86  * - at most, pbSize characters in putback area plus
87  * - at most, bufSize characters in ordinary read buffer
88  */
89  static const int pbSize = 4; // size of putback area
90  static const int bufSize = 1024; // size of the data buffer
91  char buffer[bufSize+pbSize]; // data buffer
92 
93  public:
94  fdinbuf() { fd = -1; };
95  /* constructor
96  * - initialize file descriptor
97  * - initialize empty data buffer
98  * - no putback area
99  * => force underflow()
100  */
101  fdinbuf (int _fd) : fd(_fd) {
102  setg (buffer+pbSize, // beginning of putback area
103  buffer+pbSize, // read position
104  buffer+pbSize); // end position
105  }
106 
107  void Init(int _fd){ fd = _fd; };
108  bool Ready(){ return(fd >= 0); };
109  virtual int FD() { return fd; };
110  protected:
111  // insert new characters into the buffer
112  virtual int_type underflow () {
113  using std::memcpy;
114 
115  // is read position before end of buffer?
116  if (gptr() < egptr()) {
117  return *gptr();
118  }
119 
120  /* process size of putback area
121  * - use number of characters read
122  * - but at most size of putback area
123  */
124  int numPutback;
125  numPutback = gptr() - eback();
126  if (numPutback > pbSize) {
127  numPutback = pbSize;
128  }
129 
130  /* copy up to pbSize characters previously read into
131  * the putback area
132  */
133  memcpy (buffer+(pbSize-numPutback), gptr()-numPutback,
134  numPutback);
135 
136  // read at most bufSize new characters
137  int num;
138  num = read (fd, buffer+pbSize, bufSize);
139  if (num <= 0) {
140  // ERROR or EOF
141  return EOF;
142  }
143 
144  // reset buffer pointers
145  setg (buffer+(pbSize-numPutback), // beginning of putback area
146  buffer+pbSize, // read position
147  buffer+pbSize+num); // end of buffer
148 
149  // return next character
150  return *gptr();
151  }
152  };
153 
154  class fdistream : public std::istream {
155  protected:
157  public:
158  fdistream() : std::istream(0) {};
159  fdistream (int fd) : std::istream(0), buf(fd) {
160  rdbuf(&buf);
161  };
162  int FD() { return(buf.FD()); };
163  int Init(int _fd) { buf.Init(_fd); rdbuf(&buf); return(buf.FD());};
164  };
165 
166 
167  class InProcess : public fdistream {
168  private:
169  std::string _comline;
170  FILE * _file_object;
171  public:
172  InProcess() : _file_object(NULL) {};
173  InProcess(const std::string &command) : _comline(command),_file_object(NULL)
174  {
175  _file_object = popen(_comline.c_str(),"r");
176  if(_file_object)
177  Init(fileno(_file_object));
178  }
179  virtual int Execute(const std::string &command){
180  if(_file_object)
181  pclose(_file_object);
182  _comline.assign(command);
183  _file_object = popen(_comline.c_str(),"r");
184  if(_file_object)
185  return(Init(fileno(_file_object)));
186  return(-1);
187  }
188  virtual int Finalize()
189  {
190  if(_file_object)
191  return(pclose(_file_object));
192  return(0);
193  };
194  virtual FILE *GetFile() { return(_file_object); };
195  virtual std::string Command(){ return (_comline); };
196  virtual ~InProcess(){ pclose(_file_object); };
197  };
198 
199 
200  // Class for managing the FD sets
201  class FDSetMan
202  {
203  public:
204  typedef std::vector<int> FDContainerType;
205  private:
206  fd_set readset;
207  fd_set writeset;
208  fd_set exset;
210  FDContainerType o_descriptors;
211  FDContainerType i_descriptors;
212  FDContainerType io_descriptors;
213  // std::vector<int> file_descriptors;
214  // std::map<int,sys::fdostream *> outstreams;
215  // std::map<int,sys::fdistream *> instreams;
216  public:
217  FDSetMan() : max_descriptor(-1)
218  {
219  FD_ZERO(&readset);
220  FD_ZERO(&writeset);
221  FD_ZERO(&exset);
222  o_descriptors.resize(0);
223  i_descriptors.resize(0);
224  io_descriptors.resize(0);
225  // instreams[0] = &std::cin;
226  // outstreams[1] = &std::out;
227  // outstreams[2] = &std::cerr;
228  };
229  fd_set &ReadSet() { return(readset); };
230  const fd_set ReadSet() const { return(readset); };
231  fd_set &WriteSet() { return(writeset); };
232  const fd_set WriteSet() const { return(writeset); };
233  fd_set &ExceptionSet() { return(exset); };
234  const fd_set ExceptionSet() const { return(exset); };
235  void SetOutDescriptor(int infd){
236  if(infd >= 0)
237  FD_SET(infd,&writeset);
238  if(infd > max_descriptor)
239  max_descriptor = infd;
240  };
241  void SetInDescriptor(int infd){
242  if(infd >= 0)
243  FD_SET(infd,&readset);
244  if(infd > max_descriptor)
245  max_descriptor = infd;
246  };
247  void ClearOutDescriptor(int infd){
248  if(infd >= 0)
249  FD_CLR(infd,&writeset);
250  };
251  void ClearInDescriptor(int infd){
252  if(infd >= 0)
253  FD_CLR(infd,&readset);
254  };
255  int AddOutDescriptor(int infd)
256  {
257  if(infd < 0)
258  return(-1);
259  o_descriptors.push_back(infd);
260  SetOutDescriptor(infd);
261  // if(infd > max_descriptor)
262  // max_descriptor = infd;
263  return(0);
264  };
265  int AddInDescriptor(int infd)
266  {
267  if(infd < 0)
268  return(-1);
269  i_descriptors.push_back(infd);
270  SetInDescriptor(infd);
271  return(0);
272  };
273  int AddIODescriptor(int infd)
274  {
275  if(infd < 0)
276  return(-1);
277  io_descriptors.push_back(infd);
278  SetInDescriptor(infd);
279  SetOutDescriptor(infd);
280  return(0);
281  };
282  void Zero()
283  {
284  FD_ZERO(&readset);
285  FD_ZERO(&writeset);
286  FD_ZERO(&exset);
287  };
288  void Clear(int infd)
289  {
290  if(infd >= 0){
291  FD_CLR(infd,&readset);
292  FD_CLR(infd,&writeset);
293  FD_CLR(infd,&exset);
294  }
295  };
296  void SetForRead(int infd = -1)
297  {
298  if(infd >= 0)
299  FD_SET(infd,&readset);
300  else {
301  Set(i_descriptors,&readset);
302  Set(io_descriptors,&readset,false);
303  }
304  };
305  template<class FDContainer>
306  void SetForRead(const FDContainer &fds,bool reset = true)
307  {
308  Set(fds,&readset,reset);
309  };
310  void SetForWrite(int infd = -1)
311  {
312  if(infd >= 0)
313  FD_SET(infd,&writeset);
314  else{
315  Set(o_descriptors,&writeset);
316  Set(io_descriptors,&writeset,false);
317  }
318  };
319  template<class FDContainer>
320  void SetForWrite(const FDContainer &fds)
321  {
322  Set(fds,&writeset);
323  };
324  void SetForIO(int infd = -1)
325  {
326  if(infd >= 0){
327  FD_SET(infd,&readset);
328  FD_SET(infd,&writeset);
329  }
330  else{
331  Set(i_descriptors,&readset);
332  Set(o_descriptors,&writeset);
333  Set(io_descriptors,&readset,false);
334  Set(io_descriptors,&writeset,false);
335  }
336  };
337  template<class FDContainer>
338  void SetForIO(const FDContainer &fds,bool reset = true)
339  {
340  Set(i_descriptors,&readset,reset);
341  Set(o_descriptors,&writeset,reset);
342  Set(io_descriptors,&readset,false);
343  Set(io_descriptors,&writeset,false);
344  };
345  int ReadyForOutput(int infd = -1)
346  {
347  int retval = 0;
348  if(infd >= 0)
349  retval = FD_ISSET(infd,&writeset);
350  else {
351  retval += NSet(o_descriptors,&writeset);
352  retval += NSet(io_descriptors,&writeset);
353  }
354  return(retval);
355  };
356  int ReadyForInput(int infd = -1)
357  {
358  int retval = 0;
359  if(infd >= 0){
360  retval = FD_ISSET(infd,&readset);
361  }
362  else {
363  retval += NSet(i_descriptors,&readset);
364  retval += NSet(io_descriptors,&readset);
365  }
366  return(retval);
367  };
368  template<class FDContainer>
369  int ReadyForOutput(const FDContainer &fds)
370  {
371  return(NSet(fds,&writeset));
372  };
373  template<class FDContainer>
374  int ReadyForInput(const FDContainer &fds)
375  {
376  return(NSet(fds,&readset));
377  };
378  int Select(float seconds = 0.0,bool reset = true)
379  {
380  float usec = 1.0E-6;
381  struct timeval tv;
382  struct timeval *tv_ptr = NULL;
383  if(seconds >= 0.0){
384  tv_ptr = &tv;
385  tv.tv_sec = static_cast<long>(seconds);
386  tv.tv_usec = static_cast<long>((seconds - tv.tv_sec)/usec);
387  }
388  if(reset){
389  this->Zero();
390  this->SetForRead();
391  this->SetForWrite();
392  }
393  int retval = select(max_descriptor+1,&readset,&writeset,&exset,tv_ptr);
394  if(retval < 0)
395  perror("sys::FDStreamSet::Select::select");
396  return(retval);
397  };
398  int ListenForInput(float seconds = 0.0,bool reset = true)
399  {
400  float usec = 1.0E-6;
401  struct timeval tv;
402  struct timeval *tv_ptr = NULL;
403  if(seconds >= 0.0){
404  tv_ptr = &tv;
405  tv.tv_sec = static_cast<long>(seconds);
406  tv.tv_usec = static_cast<long>((seconds - tv.tv_sec)/usec);
407  }
408  if(reset){
409  this->Zero();
410  this->SetForRead();
411  }
412  int retval = select(max_descriptor+1,&readset,NULL,&exset,tv_ptr);
413  if(retval < 0)
414  perror("sys::FDStreamSet::Select::select");
415  return(retval);
416  };
417  int ListenForOutput(float seconds = 0.0,bool reset = true)
418  {
419  float usec = 1.0E-6;
420  struct timeval tv;
421  struct timeval *tv_ptr = NULL;
422  if(seconds >= 0.0){
423  tv_ptr = &tv;
424  tv.tv_sec = static_cast<long>(seconds);
425  tv.tv_usec = static_cast<long>((seconds - tv.tv_sec)/usec);
426  }
427  if(reset){
428  this->Zero();
429  this->SetForWrite();
430  }
431  int retval = select(max_descriptor+1,NULL,&writeset,&exset,tv_ptr);
432  if(retval < 0)
433  perror("sys::FDStreamSet::Select::select");
434  return(retval);
435  };
436  template<class FDContainer>
437  int NSet(const FDContainer &fds,fd_set *fdset)
438  {
439  int retval = 0;
440  typename FDContainer::const_iterator fdi = fds.begin();
441  while(fdi != fds.end()){
442  retval += FD_ISSET(*fdi,fdset);
443  fdi++;
444  }
445  return(retval);
446  };
447  template<class FDContainer>
448  void Set(const FDContainer &fds,fd_set *fdset,bool reset = true)
449  {
450  if(reset)
451  FD_ZERO(fdset);
452  typename FDContainer::const_iterator fdi = fds.begin();
453  while(fdi != fds.end()){
454  int descriptor = *fdi++;
455  FD_SET(descriptor,fdset);
456  }
457  };
458  };
459  };
460 };
InProcess(const std::string &command)
Definition: FDUtils.H:173
int ListenForOutput(float seconds=0.0, bool reset=true)
Definition: FDUtils.H:417
std::string _comline
Definition: FDUtils.H:169
void SetForWrite(const FDContainer &fds)
Definition: FDUtils.H:320
const fd_set WriteSet() const
Definition: FDUtils.H:232
int Select(float seconds=0.0, bool reset=true)
Definition: FDUtils.H:378
int ReadyForInput(const FDContainer &fds)
Definition: FDUtils.H:374
virtual ~InProcess()
Definition: FDUtils.H:196
virtual int_type overflow(int_type c)
Definition: FDUtils.H:46
virtual int Finalize()
Definition: FDUtils.H:188
FDContainerType io_descriptors
Definition: FDUtils.H:212
int AddIODescriptor(int infd)
Definition: FDUtils.H:273
sys::fdoutbuf buf
Definition: FDUtils.H:65
STL namespace.
fd_set & ReadSet()
Definition: FDUtils.H:229
Defines MPI-specific parallel global and program classes.
fd_set & ExceptionSet()
Definition: FDUtils.H:233
int AddOutDescriptor(int infd)
Definition: FDUtils.H:255
int ReadyForOutput(const FDContainer &fds)
Definition: FDUtils.H:369
fdoutbuf(int _fd)
Definition: FDUtils.H:39
fdinbuf(int _fd)
Definition: FDUtils.H:101
void ClearInDescriptor(int infd)
Definition: FDUtils.H:251
int AddInDescriptor(int infd)
Definition: FDUtils.H:265
virtual std::string Command()
Definition: FDUtils.H:195
virtual int_type underflow()
Definition: FDUtils.H:112
void SetOutDescriptor(int infd)
Definition: FDUtils.H:235
void SetForIO(const FDContainer &fds, bool reset=true)
Definition: FDUtils.H:338
sys::fdinbuf buf
Definition: FDUtils.H:156
const fd_set ExceptionSet() const
Definition: FDUtils.H:234
bool Ready()
Definition: FDUtils.H:42
void SetForIO(int infd=-1)
Definition: FDUtils.H:324
void SetInDescriptor(int infd)
Definition: FDUtils.H:241
std::vector< int > FDContainerType
Definition: FDUtils.H:204
void SetForWrite(int infd=-1)
Definition: FDUtils.H:310
void Set(const FDContainer &fds, fd_set *fdset, bool reset=true)
Definition: FDUtils.H:448
virtual FILE * GetFile()
Definition: FDUtils.H:194
const fd_set ReadSet() const
Definition: FDUtils.H:230
void Zero(StateType &X)
fd_set & WriteSet()
Definition: FDUtils.H:231
int ReadyForOutput(int infd=-1)
Definition: FDUtils.H:345
FDContainerType o_descriptors
Definition: FDUtils.H:210
bool Ready()
Definition: FDUtils.H:108
int NSet(const FDContainer &fds, fd_set *fdset)
Definition: FDUtils.H:437
void Init(int _fd)
Definition: FDUtils.H:41
void Clear(int infd)
Definition: FDUtils.H:288
fd_set writeset
Definition: FDUtils.H:207
FILE * _file_object
Definition: FDUtils.H:170
void ClearOutDescriptor(int infd)
Definition: FDUtils.H:247
virtual int Execute(const std::string &command)
Definition: FDUtils.H:179
int Init(int _fd)
Definition: FDUtils.H:72
void SetForRead(const FDContainer &fds, bool reset=true)
Definition: FDUtils.H:306
fd_set readset
Definition: FDUtils.H:206
int ReadyForInput(int infd=-1)
Definition: FDUtils.H:356
int ListenForInput(float seconds=0.0, bool reset=true)
Definition: FDUtils.H:398
fdistream(int fd)
Definition: FDUtils.H:159
virtual int FD()
Definition: FDUtils.H:109
void Init(int _fd)
Definition: FDUtils.H:107
FDContainerType i_descriptors
Definition: FDUtils.H:211
int Init(int _fd)
Definition: FDUtils.H:163
virtual std::streamsize xsputn(const char *s, std::streamsize num)
Definition: FDUtils.H:57
fdostream(int fd)
Definition: FDUtils.H:68
virtual int FD()
Definition: FDUtils.H:43
void SetForRead(int infd=-1)
Definition: FDUtils.H:296