FileMgr.cpp
Go to the documentation of this file.
1 #include "FileMgr.h"
2 
3 #include <fstream>
4 
5 #include "GaudiKernel/ISvcLocator.h"
6 #include "GaudiKernel/IJobOptionsSvc.h"
7 
8 #include "RootFileHandler.h"
9 #include "POSIXFileHandler.h"
10 
11 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
12 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
13 
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 
17 using namespace std;
18 using namespace Io;
19 
20 
21 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23 namespace {
24 
25 void set_bit(int& f, const unsigned int& b) {
26  f |= 1 << b;
27 }
28 
29 bool get_bit(const int& f, const unsigned int& b) {
30  return f & (1 << b);
31 }
32 
33 static const std::string s_empty = "";
34 
35 constexpr struct to_name_t {
36  std::string operator()(const FileAttr* f) const { return f->name(); }
37  std::string operator()(const std::pair<std::string, FileAttr*>& f) const { return f.first; }
38 } to_name {} ;
39 
40 constexpr struct select1st_t {
41  template <typename T, typename S>
42  const T& operator()(const std::pair<T,S>& p) const { return p.first; }
43 } select1st {} ;
44 
45 constexpr struct select2nd_t {
46  template <typename T, typename S>
47  const S& operator()(const std::pair<T,S>& p) const { return p.second; }
48 } select2nd {} ;
49 
50 template <typename InputIterator, typename OutputIterator, typename UnaryOperation, typename UnaryPredicate>
51 OutputIterator transform_if( InputIterator first, InputIterator last,
52  OutputIterator result,
53  UnaryOperation op,
54  UnaryPredicate pred) {
55  while (first != last) {
56  if (pred(*first)) *result++ = op(*first);
57  ++first;
58  }
59  return result;
60 }
61 
62 template <typename InputIterator, typename OutputIterator, typename UnaryOperation, typename UnaryPredicate>
63 OutputIterator transform_copy_if( InputIterator first, InputIterator last,
64  OutputIterator result,
65  UnaryOperation op,
66  UnaryPredicate pred) {
67  while (first != last) {
68  auto t = op(*first);
69  if (pred(t)) *result++ = std::move(t);
70  ++first;
71  }
72  return result;
73 }
74 
75 }
76 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
77 
78 FileMgr::FileMgr(const std::string& name, ISvcLocator* svc)
79  : base_class( name, svc ),
80  m_log(msgSvc(), name )
81  {
82 
83  declareProperty("LogFile",m_logfile="");
84  declareProperty("PrintSummary",m_printSummary=false);
85  declareProperty("LoadROOTHandler", m_loadRootHandler=true);
86  declareProperty("LoadPOSIXHandler", m_loadPosixHandler=true);
87 
88  declareProperty("TSSL_UserProxy", m_ssl_proxy="X509");
89  declareProperty("TSSL_CertDir", m_ssl_cert="X509");
90 
91  m_lastErrS = "";
92 
93 }
94 
95 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
96 
98  // Where do the new-ed FileAttr get deleted?
99  // they get pushed into m_descriptors, but m_attr is presumably
100  // where they _also_ should be pushed in order to track ownership...
101 }
102 
103 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
104 
107 
108  // Super ugly hack to make sure we have the OutputLevel set first, so we
109  // can see DEBUG printouts in update handlers.
110  auto jos = serviceLocator()->service<IJobOptionsSvc>( "JobOptionsSvc", true );
111  const auto *props = ( jos ? jos->getProperties( name() ) : nullptr );
112  if (props) {
113  auto prop = std::find_if( std::begin(*props), std::end(*props),
114  [&](const Property* p) {
115  return p->name() == "OutputLevel";
116  });
117  if (prop!=std::end(*props)) {
118  setProperty( **prop ).ignore();
119  m_log.setLevel( m_outputLevel.value() );
120  }
121  }
122 
123  StatusCode status = Service::initialize();
124  m_log.setLevel( m_outputLevel.value() );
125 
126  if (status.isFailure()) {
127 
128  ON_DEBUG
129  m_log << MSG::DEBUG << "Failed to initialize the base class (Service)"
130  << endmsg;
131  return status;
132  }
133 
134  ON_VERBOSE
135  m_log << MSG::VERBOSE << "Initializing FileMgr" << endmsg;
136 
137  if (m_loadRootHandler.value()) {
138 
139  // setup file handler for ROOT
140 
141  msgSvc()->setOutputLevel( "RootFileHandler", m_outputLevel.value());
143 
144  auto rfh = m_rfh.get(); // used in the lambdas to avoid capturing 'this'
145  Io::FileHdlr hdlr(Io::ROOT,
146  [rfh](const std::string& n, const Io::IoFlags& f,
147  const std::string& desc, Io::Fd& fd,
148  void*& ptr) -> Io::open_t {
149  return rfh->openRootFile(n, f, desc, fd, ptr);
150  },
151  [rfh](void* ptr) -> Io::close_t {
152  return rfh->closeRootFile(ptr);
153  },
154  [rfh](void* ptr, const Io::IoFlags& f) -> Io::reopen_t {
155  return rfh->reopenRootFile(ptr, f);
156  });
157 
158  if (regHandler(hdlr).isFailure()) {
159  m_log << MSG::ERROR
160  << "unable to register ROOT file handler with FileMgr"
161  << endmsg;
162  }
163  }
164 
165  if (m_loadPosixHandler.value()) {
166 
167  // setup file handler for POSIX
168 
169  msgSvc()->setOutputLevel( "POSIXFileHandler", m_outputLevel.value());
170  m_pfh.reset( new POSIXFileHandler(msgSvc()) );
171 
172  auto pfh = m_pfh.get(); // used in the lambdas to avoid capturing 'this'
173  Io::FileHdlr hdlp(Io::POSIX,
174  [pfh](const std::string& n, const Io::IoFlags& f,
175  const std::string& desc, Io::Fd& fd,
176  void*& ptr) -> Io::open_t {
177  return pfh->openPOSIXFile(n, f, desc, fd, ptr);
178  },
179  [pfh](Io::Fd fd) -> Io::close_t {
180  return pfh->closePOSIXFile(fd);
181  },
182  [pfh](Io::Fd fd, const Io::IoFlags& f) -> Io::reopen_t {
183  return pfh->reopenPOSIXFile(fd, f);
184  });
185 
186  if (regHandler(hdlp).isFailure()) {
187  m_log << MSG::ERROR
188  << "unable to register ROOT file handler with FileMgr"
189  << endmsg;
190  }
191  }
192 
193 
194 
195  return StatusCode::SUCCESS;
196 
197 }
198 
199 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
200 
203  ON_VERBOSE
204  m_log << MSG::VERBOSE << "FileMgr::finalize()" << endmsg;
205 
206 
207  if (m_printSummary || outputLevel() <= MSG::DEBUG) {
208  listHandlers();
209  listFiles();
210  listActions();
211  listSuppression();
212  }
213 
214 
215  if (!m_files.empty()) {
217  << "At finalize, the following files remained open:"
218  << endl;
219  for (const auto& itr : m_files) m_log << *(itr.second) << endl;
220  m_log << endmsg;
221  }
222 
223  if (m_logfile.value() != "") {
224  std::ofstream ofs;
225  ofs.open(m_logfile.value().c_str());
226  if (!ofs) {
227  m_log << MSG::ERROR << "Unable to open output file \"" << m_logfile.value()
228  << "\" for writing"
229  << endmsg;
230  } else {
231  ON_DEBUG
232  m_log << MSG::DEBUG << "Saving log to \"" << m_logfile.value() << "\""
233  << endmsg;
234  for (const auto& itr : m_files) {
235  ofs << itr.second->name() << " " << itr.second->tech() << " "
236  << itr.second->desc() << " " << itr.second->iflags() << endl;
237  }
238 
239  set<FileAttr> fs;
240  for (const auto& it2 : m_oldFiles) fs.insert(*it2);
241  for (const auto& it3 : fs ) {
242  ofs << it3.name() << " " << it3.tech() << " " << it3.desc()
243  << " " << it3.iflags()
244  << ( it3.isShared() ? " SHARED" : "" )
245  << endl;
246  }
247  ofs.close();
248  }
249  }
250 
251  // cleanup FileAttrs
252  m_attr.clear();
253 
254  m_rfh.reset();
255  m_pfh.reset();
256 
257 
258  StatusCode status = Service::finalize();
259 
260  ON_DEBUG
261  if ( status.isSuccess() )
262  m_log << MSG::DEBUG << "Service finalised successfully" << endmsg;
263 
264  return status;
265 
266 }
267 
268 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
269 
270 void
271 FileMgr::handle(const Incident& /*inc*/) {
272 
273 }
274 
275 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
276 
279 
280  IoTech tech = fh.tech;
281 
282  if (m_handlers.find(tech) != m_handlers.end()) {
284  << "Handler for IoTech " << tech << " already registered. Ignoring."
285  << endmsg;
286  return StatusCode::SUCCESS;
287  }
288 
289  if ( ! fh.b_open_fcn ) {
290  m_log << MSG::ERROR
291  << "open handler for tech " << tech << " is NULL"
292  << endmsg;
293  return StatusCode::FAILURE;
294  }
295 
296  if ( ! fh.b_close_fcn && ! fh.b_closeP_fcn ) {
297  m_log << MSG::ERROR
298  << "no close handler for tech " << tech << " registered"
299  << endmsg;
300  return StatusCode::FAILURE;
301  }
302 
303  if ( ! fh.b_reopen_fcn && ! fh.b_reopenP_fcn) {
304  m_log << MSG::ERROR
305  << "no reopen handler for tech " << tech << " registered"
306  << endmsg;
307  return StatusCode::FAILURE;
308  }
309 
310 
311  ON_DEBUG
312  m_log << MSG::DEBUG
313  << "Successfully registered handler for tech \"" << tech << "\""
314  << endmsg;
315 
316  m_handlers[tech] = fh;
317 
318  return StatusCode::SUCCESS;
319 
320 }
321 
322 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
323 
326  FileHdlr hdlr;
327 
328  auto itr = m_handlers.find(tech);
329  if (itr == m_handlers.end()) {
330  m_log << MSG::ERROR << "Can't de-register tech " << tech
331  << " as it hasn't been registered!"
332  << endmsg;
333  return StatusCode::FAILURE;
334  }
335 
336  m_handlers.erase(itr);
337  return StatusCode::SUCCESS;
338 
339 }
340 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
341 
343 FileMgr::hasHandler( const IoTech& tech ) const {
344 
345  auto itr = m_handlers.find(tech);
346  return (itr != m_handlers.end()) ? StatusCode::SUCCESS : StatusCode::FAILURE;
347 
348 }
349 
350 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
351 
352 open_t
353 FileMgr::open( const IoTech& tech, const std::string& caller,
354  const std::string& fname,
355  const IoFlags& flags, Fd& fd, void*& ptr,
356  const std::string& desc, bool sh) {
357 
358  return open(tech, caller, fname, desc, flags, fd, ptr, sh);
359 
360 }
361 
362 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
363 open_t
364 FileMgr::open( const IoTech& tech, const std::string& caller,
365  const std::string& fname,
366  const IoFlags& flags, Fd& fd, const std::string& desc,
367  bool sh) {
368 
369  void* dummy(0);
370  return open(tech, caller, fname, desc, flags, fd, dummy, sh);
371 
372 }
373 
374 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
375 open_t
376 FileMgr::open( const IoTech& tech, const std::string& caller,
377  const std::string& fname,
378  const IoFlags& flags, void*& ptr, const std::string& desc,
379  bool sh) {
380 
381  Fd dummy(-1);
382  return open(tech, caller, fname, desc, flags, dummy, ptr, sh);
383 
384 }
385 
386 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
387 
388 open_t
389 FileMgr::open( const IoTech& tech, const std::string& caller,
390  const std::string& fname,
391  const std::string& desc,
392  const IoFlags& flags, Fd& fd, void*& ptr, bool shared) {
393 
394  // return codes: ok == 0, warning > 0, error < 0
395  // 0: ok
396  //
397  // WARNING:
398  // 1: file already open with existing FileAttributes
399  // 2: file already open with different FileAttributes
400  // 3: file opened, but fd and ptr are both invalid
401  //
402  // ERRORS:
403  // -1: no handler for TECH
404  // -2: file already open with different tech
405  // -3: file asked to be opened in shared mode, but other open file
406  // exist that are marked unshared
407  // -4: error calling tech specific open function
408 
409 
410  ON_VERBOSE
411  m_log << MSG::VERBOSE << "open(" << tech << ","
412  << caller
413  << ",\"" << fname << "\",\""
414  << desc << "\","
415  << flags
416  << ( shared ? ",shared" : ",unshared")
417  << ")"
418  << endmsg;
419 
420  open_t r = -1;
421  FileHdlr fh;
422  if (getHandler(tech,fh).isFailure()) return r;
423 
424 
425  auto fitr = m_files.equal_range(fname);
426 
427  // make sure all files with same name have same tech
428 
429  auto itr = std::find_if( fitr.first, fitr.second, [&](fileMap::const_reference i) { return i.second->tech()!=tech; } );
430  if (itr != fitr.second) {
431  m_log << MSG::ERROR << "when calling open on " << fname
432  << " with tech " << tech
433  << ", file already opened with different tech "
434  << itr->second->tech()
435  << endmsg;
436  r = -1;
437  return r;
438  }
439 
440 
441  // check for sharing
442 
443  if (shared) {
444 
445  bool shareable(true);
446 
447  for (auto itr=fitr.first; itr != fitr.second; ++itr) {
448  FileAttr* fa = itr->second;
449 
450  if (! fa->isShared()) shareable = false;
451 
452  // if ( shareable && accessMatch(fa->flags(),flags) )
453  if ( shareable && fa->flags().match(flags,false) ) {
454 
455  ON_DEBUG
456  m_log << MSG::DEBUG << " found shared file: "
457  << *fa << endmsg;
458 
459  fd = fa->fd();
460  ptr = fa->fptr();
461  r = 0;
462  }
463  }
464 
465  if (!shareable) {
466  // at least one of the other files was not marked shared.
467  fd = -1;
468  ptr = 0;
469  r = -1;
470  }
471  }
472 
473 
474  if (r != 0) {
475 
476  try {
477  r = fh.b_open_fcn(fname,flags,desc,fd,ptr);
478  } catch (const std::bad_function_call& err) {
479  m_log << MSG::ERROR << "when calling open handler for " << tech
480  << " on file "
481  << fname << " caught " << err.what() << endmsg;
482  return -4;
483  } catch (...) {
484  m_log << MSG::ERROR << "when calling open handler for " << tech
485  << " on file "
486  << fname << " caught an unknown exception." << endmsg;
487  return -4;
488  }
489 
490  if (r != 0) {
492  << "open of file \"" << fname << "\", tech: \"" << tech
493  << "\", flags: \"" << flags << "\" requested by "
494  << caller
495  << " failed. return code: " << r
496  << endmsg;
497 
498  FileAttr xfa(-1,fname,desc,tech,flags,0,false);
499  execAction( &xfa, caller, Io::OPEN_ERR ).ignore();
500 
501  return r;
502  }
503  }
504 
505 
506  //@TODO/@FIXME: should this not be pushed into m_attr???
507  // eg. m_attr.emplace_back( new FileAttr(fd,fname,desc,tech,flags,ptr,true,shared) );
508  // FileAttr* fa = m_attr.back().get();
509  FileAttr* fa = new FileAttr(fd,fname,desc,tech,flags,ptr,true,shared);
510 
511  ON_DEBUG
512  m_log << MSG::DEBUG << "opened file " << *fa << endmsg;
513 
514 
515  if (fd == -1 && ptr == 0) {
516  m_log << MSG::WARNING << "when opening " << *fa << " both File Descriptor"
517  << " and File Ptr are invalid" << endmsg;
518  r = 3;
519  }
520 
521 
522  for (auto itr = fitr.first; itr != fitr.second; ++itr) {
523  if (fa->flags() == Io::READ || shared) {
524  // ok
525  } else if (*fa == *(itr->second) ) {
526  m_log << MSG::WARNING << "open call for file \"" << fname
527  << "\" returned a pre-existing file with identical"
528  << " FileAttributes: " << *fa << endmsg;
529  r = 1;
530  } else {
531  m_log << MSG::WARNING << "open call for file \"" << fname
532  << "\" returned a pre-existing file with different"
533  << " FileAttributes -"
534  << endl << "old: " << *(itr->second)
535  << endl << "new: " << *fa << endmsg;
536  r = 2;
537  }
538  }
539 
540  m_files.emplace( fname,fa );
541 
542  // execute all our open callbacks
543  if (execAction( fa, caller, Io::OPEN ).isFailure()) {
545  << "at least one open callback action failed"
546  << endmsg;
547  }
548 
549 
550  return r;
551 
552 }
553 
554 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
555 
556 close_t
557 FileMgr::close( Fd fd, const std::string& caller ) {
558 
559  // return codes:
560  // < 0 : error condition
561  // 0 : actual close of one file
562  // > 0 : shared file, removed from list, no actual close, returns
563  // number of shared files still open.
564 
565  ON_VERBOSE
566  m_log << MSG::VERBOSE << "close(" << fd << ")"
567  << endmsg;
568 
569  close_t r = -1;
570 
571 
572  auto itr = std::find_if( std::begin(m_files), std::end(m_files),
573  [&](fileMap::const_reference i) { return i.second->fd() == fd; } );
574 
575 
576  if (itr == std::end(m_files)) {
577  m_log << MSG::ERROR << "unknown file descriptor \"" << fd
578  << "\" when calling close()"
579  << endmsg;
580  return r;
581  }
582 
583 
584  IoTech tech = itr->second->tech();
585 
586  FileHdlr fh;
587 
588  if (getHandler(tech,fh).isFailure()) {
589  return r;
590  }
591 
592  if (! fh.b_close_fcn) {
593  m_log << MSG::ERROR << "no close(" << tech << ",Fd) function registered"
594  << endmsg;
595  return -1;
596  }
597 
598  FileAttr* fa = itr->second;
599 
600  // find how many times this file is open
601  auto fitr = m_files.equal_range(fa->name());
602  int i = std::count_if(fitr.first, fitr.second, [&](fileMap::const_reference f) {
603  return f.second->fd()==fd; } );
604 
605  ON_VERBOSE
606  m_log << MSG::VERBOSE << " ref count: " << i
607  << endmsg;
608 
609 
610  if (i > 1 && fa->isShared()) {
611  // file open multiple times. don't do the actual close
612  ON_DEBUG
613  m_log << MSG::DEBUG << "closing file " << fa->name() << " opened "
614  << i << " times with Fd " << fd << endmsg;
615  m_files.erase(itr);
616 
617  r = i-1;
618 
619  } else if (i == 1 || (i>1 && !fa->isShared()) ) {
620  ON_DEBUG
621  m_log << "closing " << *fa << endmsg;
622 
623 
624  try {
625  r = fh.b_close_fcn(fd);
626  } catch (const std::bad_function_call& err) {
627  m_log << MSG::ERROR << "when calling close handler for " << tech
628  << " on file descriptor "
629  << fd << " caught " << err.what() << endmsg;
630  execAction(fa, caller, Io::CLOSE_ERR ).ignore();
631  return -1;
632  } catch (...) {
633  m_log << MSG::ERROR << "when calling close handler for " << tech
634  << " on file descriptor "
635  << fd << " caught an unknown exception." << endmsg;
636  execAction(fa, caller, Io::CLOSE_ERR ).ignore();
637  return -1;
638  }
639 
640  if (r < 0) {
642  << "close of file with FD \"" << fd
643  << "\", name: \"" << fa->name()
644  << "\", tech: \"" << tech << "\" failed"
645  << endmsg;
646 
647  execAction(fa, caller, Io::CLOSE_ERR ).ignore();
648 
649  return r;
650  }
651 
652  m_files.erase(itr);
653 
654  } else if (i <= 0) {
655  // this should never happen!
656  m_log << MSG::ERROR
657  << "ref count < 0 when closing " << fa
658  << ". This should never happen"
659  << endmsg;
660  return -1;
661 
662  }
663 
664  fa->fd(-1);
665  fa->flags(INVALID);
666  fa->isOpen(false);
667  fa->fptr(0);
668  m_oldFiles.push_back( fa );
669 
670 
671  // exec all callbacks
672  if (execAction(fa, caller, Io::CLOSE).isFailure()) {
674  << "at least one close callback action failed"
675  << endmsg;
676  }
677 
678 
679  return r;
680 
681 }
682 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
683 
684 close_t
685 FileMgr::close(void* vp, const std::string& caller) {
686 
687  // return codes:
688  // < 0 : error condition
689  // 0 : actual close of one file
690  // > 0 : shared file, removed from list, no actual close, returns
691  // number of shared files still open.
692 
693  ON_VERBOSE
694  m_log << MSG::VERBOSE << "close(" << vp << ")"
695  << endmsg;
696 
697  close_t r = -1;
698 
699  auto itr = std::find_if( std::begin(m_files), std::end(m_files),
700  [&](fileMap::const_reference i ) { return i.second->fptr()==vp; } );
701 
702  if (itr == m_files.end()) {
703  m_log << MSG::ERROR << "unknown file ptr \"" << vp
704  << "\" when calling close()"
705  << endmsg;
706  return r;
707  }
708 
709  IoTech tech = itr->second->tech();
710 
711  FileHdlr fh;
712 
713  if (getHandler(tech,fh).isFailure()) {
714  return r;
715  }
716  if (! fh.b_closeP_fcn) {
717  m_log << MSG::ERROR << "no close(" << tech << ",void*) function registered"
718  << endmsg;
719  return -1;
720  }
721 
722  FileAttr *fa = itr->second;
723 
724  // find how many times this file is open
725  pair<fileMap::const_iterator, fileMap::const_iterator> fitr =
726  m_files.equal_range(fa->name());
727 
728  int i = std::count_if( fitr.first, fitr.second, [&](fileMap::const_reference f)
729  { return f.second->fptr()==vp; } );
730 
731  ON_VERBOSE
732  m_log << MSG::VERBOSE << " ref count: " << i
733  << endmsg;
734 
735  if (i > 1 && fa->isShared()) {
736  // file open multiple times in shared access. don't do the actual close
737  ON_DEBUG
738  m_log << MSG::DEBUG << "closing file " << fa->name() << " opened "
739  << i << " times with fptr " << vp << endmsg;
740  m_files.erase(itr);
741 
742  r = i-1;
743 
744  } else if (i == 1 || (i>1 && !fa->isShared()) ) {
745  ON_DEBUG
746  m_log << MSG::DEBUG << "closing: " << *fa << endmsg;
747 
748  try {
749  r = fh.b_closeP_fcn(vp);
750  } catch (const std::bad_function_call& err) {
751  m_log << MSG::ERROR << "when calling close handler for " << tech
752  << " on file " << fa->name()
753  << " caught " << err.what() << endmsg;
754  execAction(fa, caller, CLOSE_ERR ).ignore();
755  return -1;
756  } catch (...) {
757  m_log << MSG::ERROR << "when calling close handler for " << tech
758  << " on file " << fa->name()
759  << " caught an unknown exception." << endmsg;
760  execAction(fa, caller, CLOSE_ERR ).ignore();
761  return -1;
762  }
763 
764  if (r < 0) {
766  << "close of file with ptr \"" << vp
767  << "\", name: \"" << fa->name()
768  << "\", tech: \"" << tech << "\" failed"
769  << endmsg;
770 
771  return r;
772  }
773 
774  m_files.erase(itr);
775 
776  } else {
777  // this should never happen!
778  m_log << MSG::ERROR
779  << "ref count: " << i << " < 0 when closing " << fa
780  << ". This should never happen"
781  << endmsg;
782  return -1;
783 
784  }
785 
786  fa->fd(-1);
787  fa->flags(INVALID);
788  fa->isOpen(false);
789  fa->fptr(0);
790  m_oldFiles.push_back( fa );
791 
792 
793  // exec all callbacks
794  if (execAction(fa, caller, CLOSE).isFailure()) {
796  << "at least one close callback action failed"
797  << endmsg;
798  }
799 
800  return r;
801 
802 }
803 
804 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
805 
806 reopen_t
807 FileMgr::reopen(Fd fd, const IoFlags& flags, const std::string& caller) {
808 
809  ON_VERBOSE
810  m_log << MSG::VERBOSE << "reopen(" << fd << "," << flags
811  << "," << caller << ")"
812  << endmsg;
813 
814  reopen_t r = -1;
815 
816 
817  auto itr = std::find_if( std::begin(m_files), std::end(m_files), [&](fileMap::const_reference f)
818  { return f.second->fd() == fd; } );
819 
820  if (itr == m_files.end()) {
821  m_log << MSG::ERROR << "unregistered FD \"" << fd
822  << "\" when calling reopen()"
823  << endmsg;
824  return r;
825  }
826 
827  FileAttr *fa = itr->second;
828  IoTech tech = fa->tech();
829 
830  FileHdlr fh;
831 
832  if (getHandler(tech,fh).isFailure()) {
833  return r;
834  }
835 
836  fa->flags( flags );
837 
838  if ( ! fh.b_reopen_fcn ) {
839  m_log << MSG::ERROR << "no reopen(" << tech << ",Fd) function registered"
840  << endmsg;
841  return -1;
842  }
843 
844 // FIXME: what does it mean to call reopen on a shared file?
845 
846 
847  try {
848  r = fh.b_reopen_fcn(fd,flags);
849  } catch (const std::bad_function_call& err) {
850  m_log << MSG::ERROR << "when calling reopen handler for " << tech
851  << " on file descriptor " << fd << " with flags "
852  << flags
853  << " caught " << err.what() << endmsg;
854  return -1;
855  } catch (...) {
856  m_log << MSG::ERROR << "when calling reopen handler for " << tech
857  << " on file descriptor " << fd << " with flags "
858  << flags
859  << " caught an unknown exception." << endmsg;
860  return -1;
861  }
862 
863  if (r < 0) {
865  << "reopen of file with FD \"" << fd
866  << "\", name: \"" << fa->name()
867  << "\", tech: \"" << tech
868  << "\", flags: \"" << flags << "\" failed"
869  << endmsg;
870 
871  execAction(fa, caller, Io::REOPEN_ERR ).ignore();
872 
873  return r;
874 
875  }
876 
877  fa->isOpen(true);
878  fa->flags(flags);
879 
880  // exec all callbacks
881  if (execAction(fa, caller, Io::REOPEN).isFailure()) {
883  << "at least one reopen callback action failed"
884  << endmsg;
885  }
886 
887  return r;
888 
889 }
890 
891 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
892 
893 reopen_t
894 FileMgr::reopen(void* vp, const IoFlags& flags, const std::string& caller) {
895  ON_VERBOSE
896  m_log << MSG::VERBOSE << "reopen(" << vp << "," << flags
897  << "," << caller << ")"
898  << endmsg;
899 
900  reopen_t r = -1;
901 
902  auto itr = std::find_if( std::begin(m_files), std::end(m_files),
903  [&](fileMap::const_reference f) {
904  return f.second->fptr() == vp ; } );
905  if (itr == m_files.end()) {
906  m_log << MSG::ERROR
907  << "unregistered file ptr \"" << vp
908  << "\" when calling reopen()"
909  << endmsg;
910  return r;
911  }
912 
913  FileAttr *fa = itr->second;
914  FileHdlr fh;
915  IoTech tech = fa->tech();
916 
917  if (getHandler(tech,fh).isFailure()) {
918  return r;
919  }
920 
921  if ( ! fh.b_reopenP_fcn ) {
922  m_log << MSG::ERROR << "no reopen(" << tech << ",void*) function registered"
923  << endmsg;
924  return -1;
925  }
926 
927  try {
928  r = fh.b_reopenP_fcn(vp,flags);
929  } catch (const std::bad_function_call& err) {
930  m_log << MSG::ERROR << "when calling reopen handler for " << tech
931  << " on file " << fa->name() << " with flags "
932  << flags
933  << " caught " << err.what() << endmsg;
934  return -1;
935  } catch (...) {
936  m_log << MSG::ERROR << "when calling reopen handler for " << tech
937  << " on file " << fa->name() << " with flags "
938  << flags
939  << " caught an unknown exception." << endmsg;
940  return -1;
941  }
942 
943  if (r < 0) {
945  << "reopen of file with ptr \"" << vp
946  << "\", name: \"" << fa->name()
947  << "\", tech: \"" << tech
948  << "\", flags: \"" << flags << "\" failed"
949  << endmsg;
950 
951  execAction(fa, caller, Io::REOPEN_ERR ).ignore();
952 
953  return r;
954 
955  }
956 
957  fa->isOpen(true);
958  fa->flags(flags);
959 
960  // exec all callbacks
961  if (execAction(fa, caller, Io::REOPEN).isFailure()) {
963  << "at least one reopen callback action failed"
964  << endmsg;
965  }
966 
967  return r;
968 
969 }
970 
971 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
972 
973 int
974 FileMgr::getFileAttr(const std::string& fname, vector<const FileAttr*>& fa) const {
975 
976  fa.clear();
977 
978  auto fitr = m_files.equal_range(fname);
979  std::transform( fitr.first, fitr.second, std::back_inserter(fa), select2nd );
980 
981  std::copy_if( std::begin(m_oldFiles), std::end(m_oldFiles),
982  std::back_inserter(fa), [&](const FileAttr* f ) { return f->name() == fname; } );
983 
984  return fa.size();
985 
986 }
987 
988 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
989 
991 FileMgr::getFileAttr(const Fd fd, const FileAttr*& fa) const {
992 
993  auto i = std::find_if( std::begin(m_files), std::end(m_files),
994  [&](fileMap::const_reference f ) { return f.second->fd() == fd; } );
995  if (i != std::end(m_files)) {
996  fa = i->second;
997  return StatusCode::SUCCESS;
998  }
999 
1000  auto j = std::find_if( std::begin(m_oldFiles), std::end(m_oldFiles),
1001  [&](const FileAttr* f) { return f->fd() == fd; } );
1002  if (j != std::end(m_oldFiles)) {
1003  fa = *j;
1004  return StatusCode::SUCCESS;
1005  }
1006 
1007  return StatusCode::FAILURE;
1008 
1009 }
1010 
1011 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1012 
1013 StatusCode
1014 FileMgr::getFileAttr(void* vp, const FileAttr*& fa) const {
1015 
1016  auto i = std::find_if( std::begin(m_files), std::end(m_files),
1017  [&](fileMap::const_reference f) { return f.second->fptr() == vp; } );
1018  if (i != std::end(m_files)) {
1019  fa = i->second;
1020  return StatusCode::SUCCESS;
1021  }
1022 
1023  auto j = std::find_if( std::begin(m_oldFiles), std::end(m_oldFiles),
1024  [&](const FileAttr* f) { return f->fptr() == vp; } );
1025  if (j != std::end(m_oldFiles)) {
1026  fa = *j;
1027  return StatusCode::SUCCESS;
1028  }
1029 
1030  return StatusCode::FAILURE;
1031 
1032 }
1033 
1034 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1035 
1036 int
1037 FileMgr::getFiles(std::vector<std::string>& files, bool op) const {
1038 
1039  files.clear();
1040  auto not_in_files = [&](const std::string& i) { return std::none_of( std::begin(files), std::end(files),
1041  [&](const std::string& j) { return j==i; } ); };
1042  transform_copy_if( std::begin(m_files), std::end(m_files), std::back_inserter(files),
1043  to_name,
1044  not_in_files );
1045  if (!op) {
1046  transform_copy_if( std::begin(m_oldFiles), std::end(m_oldFiles), std::back_inserter(files),
1047  to_name,
1048  not_in_files );
1049  }
1050  return files.size();
1051 }
1052 
1053 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1054 
1055 int
1056 FileMgr::getFiles(vector<const Io::FileAttr*>& files, bool op) const {
1057 
1058  files.clear();
1059  std::transform(std::begin(m_files), std::end(m_files), std::back_inserter(files),
1060  select2nd );
1061  if (!op) {
1062  std::copy(std::begin(m_oldFiles), std::end(m_oldFiles), std::back_inserter(files));
1063  }
1064  return files.size();
1065 
1066 }
1067 
1068 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1069 
1070 int
1071 FileMgr::getFiles(const IoTech& tech, vector<string>& files, bool op) const {
1072 
1073  if (tech == UNKNOWN) return getFiles(files,op);
1074 
1075  files.clear();
1076  transform_if( std::begin(m_files), std::end(m_files), std::back_inserter(files),
1077  to_name,
1078  [&](fileMap::const_reference f) { return f.second->tech() == tech &&
1079  std::none_of( std::begin(files), std::end(files), [&](const std::string& j) { return j==f.first; } ); } );
1080 
1081  if (!op) {
1082  transform_if( std::begin(m_oldFiles), std::end(m_oldFiles), std::back_inserter(files),
1083  to_name,
1084  [&](const FileAttr* f) { return f->tech() == tech &&
1085  std::none_of( std::begin(files), std::end(files), [&](const std::string& j) { return j == f->name(); } ) ; } );
1086  }
1087  return files.size();
1088 
1089 }
1090 
1091 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1092 
1093 int
1094 FileMgr::getFiles(const IoTech& tech, vector<const Io::FileAttr*>& files,
1095  bool op) const {
1096 
1097  if (tech == UNKNOWN) return getFiles(files,op);
1098 
1099  auto matches_tech = [&](const FileAttr* f) { return f->tech()==tech; } ;
1100 
1101  files.clear();
1102  transform_copy_if( std::begin(m_files), std::end(m_files), std::back_inserter(files),
1103  select2nd, matches_tech );
1104  if (!op) {
1105  std::copy_if( std::begin(m_oldFiles), std::end(m_oldFiles), std::back_inserter(files),
1106  matches_tech );
1107  }
1108 
1109  return files.size();
1110 
1111 }
1112 
1113 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1114 
1115 int
1116 FileMgr::getFiles(const IoTech& tech, const IoFlags& flags,
1117  vector<string>& files, bool op) const {
1118 
1119  files.clear();
1120 
1121  auto not_in_files = [&](const std::string& n) { return std::none_of( std::begin(files), std::end(files),
1122  [&](const std::string& f) { return f==n; } ); };
1123  auto matches_tech_and_flags = [&](const FileAttr* f) { return ( f->tech() == tech || tech == UNKNOWN ) && f->flags() == flags ; } ;
1124 
1125  transform_if( std::begin(m_files), std::end(m_files), std::back_inserter(files),
1126  to_name,
1127  [&](fileMap::const_reference f) { return matches_tech_and_flags( f.second ) && not_in_files( f.first ); } );
1128  if (!op) {
1129  transform_if( std::begin(m_oldFiles), std::end(m_oldFiles), std::back_inserter(files),
1130  to_name,
1131  [&](const FileAttr* f) { return matches_tech_and_flags(f) && not_in_files(f->name()); } );
1132  }
1133 
1134  return files.size();
1135 
1136 }
1137 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1138 
1139 int
1140 FileMgr::getFiles(const IoTech& tech, const IoFlags& flags,
1141  vector<const Io::FileAttr*>& files, bool op) const {
1142 
1143  files.clear();
1144 
1145  auto matches_tech_and_flags = [&](const FileAttr* f) { return ( f->tech() == tech || tech == UNKNOWN )
1146  && f->flags() == flags ; } ;
1147 
1148  transform_copy_if( std::begin(m_files), std::end(m_files), std::back_inserter(files),
1149  select2nd,
1150  matches_tech_and_flags );
1151  if (!op) {
1152  std::copy_if( std::begin(m_oldFiles), std::end(m_oldFiles), std::back_inserter(files),
1153  matches_tech_and_flags );
1154  }
1155 
1156  return files.size();
1157 }
1158 
1159 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1160 
1161 // get all descriptors known
1162 // return number found
1163 
1164 int
1165 FileMgr::getFd(vector<Fd>& fd) const {
1166 
1167  std::transform( std::begin(m_descriptors), std::end(m_descriptors),
1168  std::back_inserter(fd), select1st );
1169  return m_descriptors.size();
1170 
1171 }
1172 
1173 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1174 
1175 // get all descriptors given tech
1176 // return number found
1177 
1178 int
1179 FileMgr::getFd(const IoTech& tech, vector<Fd>& fd) const {
1180 
1181  if (tech == UNKNOWN) return getFd( fd );
1182 
1183  fd.clear();
1184  transform_if( std::begin(m_descriptors), std::end(m_descriptors), std::back_inserter(fd),
1185  select1st,
1186  [&](const std::pair<Fd,FileAttr*>& d) { return d.second->tech()==tech; } );
1187 
1188  return fd.size();
1189 
1190 }
1191 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1192 
1193 // get all descriptors of given tech and flags
1194 // return number found
1195 
1196 int
1197 FileMgr::getFd(const IoTech& tech, const IoFlags& flags, vector<Fd>& fd) const {
1198 
1199  fd.clear();
1200  transform_if( m_descriptors.begin(), m_descriptors.end(),
1201  std::back_inserter(fd), select1st,
1202  [&](const std::pair<Fd,FileAttr*>& d) {
1203  return (d.second->tech() == tech || tech == UNKNOWN) &&
1204  ( d.second->flags() == flags );
1205  } );
1206  return fd.size();
1207 }
1208 
1209 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1210 
1211 const std::string&
1212 FileMgr::fname(const Io::Fd& fd) const {
1213 
1214  auto itr = std::find_if( std::begin(m_files), std::end(m_files),
1215  [&](fileMap::const_reference f) { return f.second->fd() == fd; } );
1216  return (itr!=std::end(m_files)) ? itr->second->name() : s_empty;
1217 
1218 }
1219 
1220 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1221 
1222 const std::string&
1223 FileMgr::fname(void* vp) const {
1224 
1225  auto itr = std::find_if( m_files.begin(), m_files.end(),
1226  [&](fileMap::const_reference f) {
1227  return f.second->fptr() == vp;
1228  });
1229  return itr!=m_files.end() ? itr->second->name() : s_empty;
1230 }
1231 
1232 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1233 
1234 Io::Fd
1235 FileMgr::fd(const std::string& fname) const {
1236 
1237  auto fitr = m_files.equal_range(fname);
1238  auto itr = std::find_if( fitr.first, fitr.second, [](fileMap::const_reference f) {
1239  return f.second->fd() != -1;
1240  } );
1241  return itr!=fitr.second ? itr->second->fd() : -1 ;
1242 }
1243 
1244 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1245 
1246 Io::Fd
1247 FileMgr::fd(void* fptr) const {
1248 
1249  auto itr = std::find_if(m_files.begin(),m_files.end(),[&](fileMap::const_reference f) {
1250  return f.second->fptr() == fptr;
1251  } );
1252  return itr!=m_files.end() ? itr->second->fd() : -1 ;
1253 }
1254 
1255 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1256 
1257 void*
1258 FileMgr::fptr(const std::string& fname) const {
1259  auto fitr = m_files.equal_range(fname);
1260  auto itr = std::find_if( fitr.first, fitr.second, [](fileMap::const_reference f) -> bool {
1261  return f.second->fptr();
1262  } );
1263  return itr!=fitr.second ? itr->second->fptr() : nullptr;
1264 }
1265 
1266 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1267 
1268 void*
1269 FileMgr::fptr(const Io::Fd& fd) const {
1270 
1271  auto itr = std::find_if(m_files.begin(),m_files.end(),[&](fileMap::const_reference f) {
1272  return f.second->fd() == fd;
1273  } );
1274  return itr!=m_files.end() ? itr->second->fptr() : nullptr;
1275 }
1276 
1277 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1278 
1279 void
1281 
1282  m_log << MSG::INFO << "listing registered files ["
1283  << (m_files.size() + m_oldFiles.size() )
1284  << "]:" << endl;
1285 
1286  for (auto& itr : m_files ) m_log << itr.second << endl;
1287  for (auto& it2 : m_oldFiles ) m_log << *it2 << endl;
1288 
1289  m_log << endmsg;
1290 }
1291 
1292 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1293 
1294 int
1295 FileMgr::getLastError(std::string& err) const {
1296 
1297  err = m_lastErrS;
1298  return m_lastErr;
1299 
1300 }
1301 
1302 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1303 
1304 StatusCode
1305 FileMgr::getHandler(const Io::IoTech& tech, Io::FileHdlr& hdlr) const {
1306 
1307  auto itr = m_handlers.find(tech);
1308  if (itr == m_handlers.end()) {
1309  m_log << MSG::ERROR
1310  << "no handler for tech " << tech << " registered"
1311  << endmsg;
1312  return StatusCode::FAILURE;
1313  }
1314  hdlr = itr->second;
1315  return StatusCode::SUCCESS;
1316 }
1317 
1318 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1319 
1320 StatusCode
1321 FileMgr::getHandler(const std::string& fname, Io::FileHdlr& hdlr) const {
1322 
1323  auto fitr = m_files.equal_range(fname);
1324  if (fitr.first == fitr.second) {
1325  m_log << MSG::ERROR
1326  << "no file \"" << fname << "\" registered. Cannot determine tech"
1327  << endmsg;
1328  return StatusCode::FAILURE;
1329  }
1330 
1331  auto itr = fitr.first;
1332  IoTech tech = itr->second->tech();
1333 
1334  ++itr;
1335  while( itr != fitr.second ) {
1336  if ( itr->second->tech() != tech ) {
1337  m_log << MSG::ERROR
1338  << "multiple technologies registered for file \"" << fname
1339  << "\". Cannot determine handler" << endmsg;
1340  return StatusCode::FAILURE;
1341  }
1342  ++itr;
1343  }
1344 
1345  return getHandler(tech,hdlr);
1346 
1347 }
1348 
1349 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1350 
1351 void
1353 
1354  m_log << MSG::INFO
1355  << "Listing registered handlers:" << endl;
1356 
1357  for (const auto& itr : m_handlers ) m_log << " " << itr.first << endl;
1358  m_log << endmsg;
1359 
1360 }
1361 
1362 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1363 
1364 StatusCode
1365 FileMgr::regAction(bfcn_action_t bf, const Io::Action& a, const std::string& d) {
1366 
1367  return regAction(bf,a,Io::UNKNOWN,d);
1368 
1369 }
1370 
1371 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1372 
1373 StatusCode
1375  const std::string& d) {
1376 
1377  ON_DEBUG
1378  m_log << MSG::DEBUG << "registering " << a << " action "
1379  << System::typeinfoName(bf.target_type())
1380  << " for tech " << t << endmsg;
1381 
1382  m_actions[t][a].emplace_back(bf, (!d.empty()) ? d
1383  : System::typeinfoName(bf.target_type()));
1384  return StatusCode::SUCCESS;
1385 
1386 }
1387 
1388 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1389 
1390 void
1392 
1393  m_log << MSG::INFO << "listing registered actions" << endl;
1394 
1395  for (const auto& iit : m_actions) {
1396  Io::IoTech t = iit.first;
1397  const actionMap& m = iit.second;
1398 
1399  if (!m.empty()) {
1400  m_log << " --- Tech: ";
1401  if (t == Io::UNKNOWN) {
1402  m_log << "ALL ---" << endl;
1403  } else {
1404  m_log << t << " ---" << endl;
1405  }
1406  for (const auto& iia : m ) {
1407  for (const auto& it2 : iia.second ) {
1408  m_log << " " << iia.first << " "
1409  << it2.second << endl;
1410  }
1411  }
1412  }
1413  }
1414  m_log << endmsg;
1415 }
1416 
1417 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1418 
1419 StatusCode
1420 FileMgr::execAction( Io::FileAttr* fa, const std::string& caller,
1421  const Io::Action& a) const {
1422 
1423  Io::IoTech tech = fa->tech();
1424 
1425  StatusCode s1,s2;
1426 
1427  auto itr = m_actions.find(Io::UNKNOWN);
1428 
1429  if (itr != m_actions.end() && !itr->second.empty() ) {
1430  s1 = execActs(fa, caller, a, itr->second);
1431  }
1432 
1433  itr = m_actions.find(tech);
1434  if (itr != m_actions.end() && !itr->second.empty() ) {
1435  s2 = execActs(fa, caller, a, itr->second);
1436  }
1437 
1438  return (s1.isFailure() || s2.isFailure()) ? StatusCode::FAILURE
1440 }
1441 
1442 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1443 
1444 StatusCode
1445 FileMgr::execActs(Io::FileAttr* fa, const std::string& caller,
1446  const Io::Action& a, const actionMap& m) const {
1447 
1448  auto mitr = m.find(a);
1449 
1450  if (mitr == m.end() || mitr->second.empty()) {
1451  return StatusCode::SUCCESS;
1452  }
1453 
1454  ON_DEBUG
1455  m_log << MSG::DEBUG
1456  << "executing " << mitr->second.size() << " " << a
1457  << " actions on "
1458  << *fa << " from "
1459  << caller
1460  << endmsg;
1461 
1462 
1463  bool fail(false);
1464 
1465  auto it2 = m_supMap.find(fa->name());
1466  if (it2 != m_supMap.end()) {
1467  if (get_bit(it2->second,a) || get_bit(it2->second,Io::INVALID_ACTION)) {
1468  ON_DEBUG
1469  m_log << MSG::DEBUG << " --> suppressing callback action for "
1470  << a
1471  << endmsg;
1472  return StatusCode::SUCCESS;
1473  }
1474  }
1475 
1476  for (const auto& itr : mitr->second ) {
1477 
1478  ON_DEBUG
1479  m_log << MSG::DEBUG << "executing "
1480  << itr.second << endmsg;
1481 
1482  if ( (((itr.first))(fa,caller)).isFailure() ) {
1483  m_log << MSG::WARNING << "execution of "
1484  << itr.second << " on " << *fa
1485  << " failed during " << a << " action"
1486  << endmsg;
1487  fail = true;
1488  }
1489 
1490  }
1491 
1492  return fail ? StatusCode::FAILURE : StatusCode::SUCCESS;
1493 
1494 }
1495 
1496 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1497 
1498 bool
1500  bool /*strict*/) const {
1501 
1502  ON_VERBOSE
1503  m_log << MSG::VERBOSE << "accessMatch old: " << fold
1504  << " new: " << fnew
1505  << endmsg;
1506 
1507  return ( ((fold == Io::READ) && (fnew == Io::READ)) ||
1508  ( (fold & Io::WRITE) != 0 && (fnew & Io::WRITE) != 0) ||
1509  ( (fold & Io::RDWR) != 0 && (fnew & Io::RDWR) != 0) ) ;
1510 
1511 }
1512 
1513 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1514 
1515 void
1516 FileMgr::suppressAction(const std::string& f) {
1517 
1519 
1520 }
1521 
1522 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1523 
1524 void
1525 FileMgr::suppressAction(const std::string& f, const Io::Action& a) {
1526 
1527  auto it2 = m_supMap.find(f);
1528  if (it2 == m_supMap.end()) {
1529  int b(0);
1530  set_bit(b,a);
1531  m_supMap[f] = b;
1532  } else {
1533  set_bit(it2->second, a);
1534  }
1535 
1536 }
1537 
1538 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1539 
1540 void
1542 
1543  if (m_supMap.empty()) return;
1544 
1545  m_log << MSG::INFO << "listing suppressed file actions" << endl;
1546 
1547  for (auto it2=m_supMap.begin(); it2 != m_supMap.end(); ++it2) {
1548  m_log << " " << it2->first;
1549  if (get_bit(it2->second, Io::INVALID_ACTION)) {
1550  m_log << " ALL" << endl;
1551  } else {
1552  for (int i=0; i<Io::INVALID_ACTION; ++i) {
1553  if (get_bit(it2->second,i)) { m_log << " " << (Io::Action)i; }
1554  }
1555  m_log << endl;
1556  }
1557  }
1558 
1559  m_log << endmsg;
1560 }
std::vector< std::unique_ptr< FileAttr > > m_attr
Definition: FileMgr.h:157
StatusCode regHandler(FileHdlr) override
Definition: FileMgr.cpp:278
StatusCode getHandler(const IoTech &, FileHdlr &) const override
IoTech
Definition: IFileMgr.h:150
Io::Fd fd(const std::string &) const override
Definition: FileMgr.cpp:1235
StringProperty m_logfile
Definition: FileMgr.h:132
StatusCode initialize() override
Definition: Service.cpp:63
Definition: IFileMgr.h:19
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode finalize() override
Definition: Service.cpp:188
std::function< StatusCode(FILEMGR_CALLBACK_ARGS) > bfcn_action_t
Definition: IFileMgr.h:309
const std::string & name() const
property name
Definition: Property.h:45
int reopen_t
Definition: IFileMgr.h:254
int Fd
Definition: IFileMgr.h:172
Io::open_t open(const Io::IoTech &, const std::string &caller, const std::string &fname, const Io::IoFlags &, Io::Fd &fd, void *&ptr, const std::string &desc="", const bool shared=false) override
Definition: FileMgr.cpp:353
constexpr struct select1st_t select1st
bfcn_reopen_t b_reopen_fcn
Definition: IFileMgr.h:269
void suppressAction(const std::string &) override
Definition: FileMgr.cpp:1516
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:297
MsgStream m_log
Definition: FileMgr.h:171
supMap m_supMap
Definition: FileMgr.h:164
void * fptr() const
Definition: IFileMgr.h:190
fileMap m_files
Definition: FileMgr.h:154
int open_t
Definition: IFileMgr.h:252
std::map< Io::Action, std::list< bfcn_desc_t > > actionMap
Definition: FileMgr.h:142
STL namespace.
bool isOpen() const
Definition: IFileMgr.h:191
int getLastError(std::string &) const override
Definition: FileMgr.cpp:1295
StatusCode deregHandler(const IoTech &) override
Definition: FileMgr.cpp:325
StatusCode execAction(Io::FileAttr *, const std::string &, const Io::Action &) const
Definition: FileMgr.cpp:1420
std::map< Fd, FileAttr * > m_descriptors
Definition: FileMgr.h:156
Fd fd() const
Definition: IFileMgr.h:184
StatusCode hasHandler(const IoTech &) const override
Definition: FileMgr.cpp:343
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
bool accessMatch(const Io::IoFlags &, const Io::IoFlags &, bool strict=false) const
Definition: FileMgr.cpp:1499
std::unique_ptr< RootFileHandler > m_rfh
Definition: FileMgr.h:169
virtual void listActions() const
Definition: FileMgr.cpp:1391
Action
Definition: IFileMgr.h:290
const std::string & name() const
Definition: IFileMgr.h:185
std::map< IoTech, FileHdlr > m_handlers
Definition: FileMgr.h:155
Main interface for the JobOptions service.
bool isShared() const
Definition: IFileMgr.h:192
void handle(const Incident &) override
Definition: FileMgr.cpp:271
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
constexpr double m
Definition: SystemOfUnits.h:93
bfcn_close_t b_close_fcn
Definition: IFileMgr.h:267
Io::reopen_t reopen(const Fd, const IoFlags &, const std::string &caller) override
StatusCode execActs(Io::FileAttr *, const std::string &, const Io::Action &, const actionMap &m) const
Definition: FileMgr.cpp:1445
bfcn_closeP_t b_closeP_fcn
Definition: IFileMgr.h:268
BooleanProperty m_printSummary
Definition: FileMgr.h:133
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Definition: Bootstrap.cpp:254
Io::close_t close(const Fd, const std::string &caller) override
std::unique_ptr< POSIXFileHandler > m_pfh
Definition: FileMgr.h:170
bfcn_reopenP_t b_reopenP_fcn
Definition: IFileMgr.h:270
int getFileAttr(const std::string &, std::vector< const FileAttr * > &) const override
Definition: FileMgr.cpp:974
#define DECLARE_SERVICE_FACTORY(x)
Definition: Service.h:354
const TYPE & value() const
explicit conversion
Definition: Property.h:341
std::string m_lastErrS
Definition: FileMgr.h:166
StatusCode regAction(Io::bfcn_action_t, const Io::Action &, const std::string &desc="") override
Definition: FileMgr.cpp:1365
FileMgr(const std::string &name, ISvcLocator *svc)
Definition: FileMgr.cpp:78
BooleanProperty m_loadRootHandler
Definition: FileMgr.h:133
std::vector< FileAttr * > m_oldFiles
Definition: FileMgr.h:159
bfcn_open_t b_open_fcn
Definition: IFileMgr.h:266
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:38
const std::string & fname(const Io::Fd &) const override
Definition: FileMgr.cpp:1212
BooleanProperty m_loadPosixHandler
Definition: FileMgr.h:133
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
virtual void listSuppression() const
Definition: FileMgr.cpp:1541
IoTech tech() const
Definition: IFileMgr.h:187
bool match(const IoFlags &fa, bool strict=true) const
Definition: IFileMgr.h:59
void * fptr(const std::string &) const override
Definition: FileMgr.cpp:1258
StringProperty m_ssl_cert
Definition: FileMgr.h:134
Base class for all Incidents (computing events).
Definition: Incident.h:16
void setLevel(int level)
Update outputlevel.
Definition: MsgStream.h:106
int m_lastErr
Definition: FileMgr.h:167
int getFiles(std::vector< std::string > &, bool onlyOpen=true) const override
Definition: FileMgr.cpp:1037
#define ON_DEBUG
Definition: FileMgr.cpp:11
void ignore() const
Definition: StatusCode.h:108
void listFiles() const override
Definition: FileMgr.cpp:1280
StringProperty m_ssl_proxy
Definition: FileMgr.h:134
void listHandlers() const override
Definition: FileMgr.cpp:1352
~FileMgr() override
Definition: FileMgr.cpp:97
list i
Definition: ana.py:128
IoFlags flags() const
Definition: IFileMgr.h:188
int getFd(std::vector< Fd > &) const override
StatusCode finalize() override
Definition: FileMgr.cpp:202
#define ON_VERBOSE
Definition: FileMgr.cpp:12
IoTech tech
Definition: IFileMgr.h:264
int close_t
Definition: IFileMgr.h:253
StatusCode initialize() override
Definition: FileMgr.cpp:106
std::map< IoTech, actionMap > m_actions
Definition: FileMgr.h:161