irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

irods_load_plugin.hpp
Go to the documentation of this file.
1 #ifndef __IRODS_LOAD_PLUGIN_HPP__
2 #define __IRODS_LOAD_PLUGIN_HPP__
3 
4 // =-=-=-=-=-=-=-
5 // My Includes
6 #include "irods_log.hpp"
9 #include "getRodsEnv.h"
10 #include "rodsErrorTable.h"
11 #include "irods_default_paths.hpp"
12 #include "irods_exception.hpp"
13 
14 // =-=-=-=-=-=-=-
15 // STL Includes
16 #include <string>
17 #include <sstream>
18 #include <iostream>
19 #include <algorithm>
20 
21 // =-=-=-=-=-=-=-
22 // Boost Includes
23 #include <boost/static_assert.hpp>
24 #include <boost/filesystem.hpp>
25 
26 // =-=-=-=-=-=-=-
27 // dlopen, etc
28 #include <dlfcn.h>
29 
30 
31 namespace irods {
32 
34  const std::string& _type,
35  std::string& _path ) {
36  namespace fs = boost::filesystem;
37  fs::path plugin_home;
38 
39  rodsEnv env;
40  int status = getRodsEnv( &env );
41  if ( !status ) {
42  if ( strlen( env.irodsPluginHome ) > 0 ) {
43  plugin_home = env.irodsPluginHome;
44  }
45 
46  }
47 
48  if (plugin_home.empty()) {
49  try {
50  plugin_home = get_irods_default_plugin_directory();
51  } catch (const irods::exception& e) {
52  irods::log(e);
53  return ERROR(SYS_INVALID_INPUT_PARAM, "failed to get default plugin directory");
54  }
55  }
56 
57  plugin_home.append(_type);
58 
59  try {
60  if ( !fs::exists( plugin_home ) ) {
61  std::string msg( "does not exist [" );
62  msg += plugin_home.string();
63  msg += "]";
64  return ERROR(
66  msg );
67 
68  }
69 
70  fs::path p = fs::canonical( plugin_home );
71 
72  _path = plugin_home.string();
73 
74  if ( fs::path::preferred_separator != *_path.rbegin() ) {
75  _path += fs::path::preferred_separator;
76  }
77 
78  rodsLog(
79  LOG_DEBUG,
80  "resolved plugin home [%s]",
81  _path.c_str() );
82 
83  return SUCCESS();
84 
85  }
86  catch ( const fs::filesystem_error& _e ) {
87  std::string msg( "does not exist [" );
88  msg += plugin_home.string();
89  msg += "]\n";
90  msg += _e.what();
91  return ERROR(
93  msg );
94  }
95 
96  } // resolve_plugin_path
97 
125  template< typename PluginType, typename ...Ts >
126  error load_plugin( PluginType*& _plugin,
127  const std::string& _plugin_name,
128  const std::string& _interface,
129  const std::string& _instance_name,
130  const Ts&... _args ) {
131  namespace fs = boost::filesystem;
132 
133  // resolve the plugin path
134  std::string plugin_home;
135  error ret = resolve_plugin_path( _interface, plugin_home );
136  if( !ret.ok() ) {
137  return PASS( ret );
138  }
139 
140  // Generate the shared lib name
141  std::string so_name;
142  plugin_name_generator name_gen;
143  ret = name_gen( _plugin_name, plugin_home, so_name );
144  if ( !ret.ok() ) {
145  std::stringstream msg;
146  msg << __FUNCTION__;
147  msg << " - Failed to generate an appropriate shared library name for plugin: \"";
148  msg << _plugin_name << "\".";
149  return PASSMSG( msg.str(), ret );
150  }
151 
152  try {
153  if ( !fs::exists( so_name ) ) {
154  std::string msg( "shared library does not exist [" );
155  msg += so_name;
156  msg += "]";
158  }
159  }
160  catch ( const fs::filesystem_error& _e ) {
161  std::string msg( "boost filesystem exception when checking existence of [" );
162  msg += so_name;
163  msg += "] with message [";
164  msg += _e.what();
165  msg += "]";
167  }
168 
169  // =-=-=-=-=-=-=-
170  // try to open the shared object
171  void* handle = dlopen( so_name.c_str(), RTLD_LAZY | RTLD_LOCAL );
172  if ( !handle ) {
173  std::stringstream msg;
174  msg << "failed to open shared object file [" << so_name
175  << "] :: dlerror: is [" << dlerror() << "]";
176  return ERROR( PLUGIN_ERROR, msg.str() );
177  }
178 
179  // =-=-=-=-=-=-=-
180  // clear any existing dlerrors
181  dlerror();
182 
183  // =-=-=-=-=-=-=-
184  // attempt to load the plugin factory function from the shared object
185  typedef PluginType* ( *factory_type )( const std::string& , const Ts&... );
186  factory_type factory = reinterpret_cast< factory_type >( dlsym( handle, "plugin_factory" ) );
187  char* err = dlerror();
188  if ( 0 != err || !factory ) {
189  std::stringstream msg;
190  msg << "failed to load symbol from shared object handle - plugin_factory"
191  << " :: dlerror is [" << err << "]";
192  dlclose( handle );
193  return ERROR( PLUGIN_ERROR, msg.str() );
194  }
195 
196  rodsLog(LOG_DEBUG, "load_plugin - calling plugin_factory() in [%s]", so_name.c_str());
197 
198  // =-=-=-=-=-=-=-
199  // using the factory pointer create the plugin
200  _plugin = factory( _instance_name, _args... );
201  if ( !_plugin ) {
202  std::stringstream msg;
203  msg << "failed to create plugin object for [" << _plugin_name << "]";
204  dlclose( handle );
205  return ERROR( PLUGIN_ERROR, msg.str() );
206  }
207 
208  // =-=-=-=-=-=-=-
209  // notify world of success
210  // TODO :: add hash checking and provide hash value for log also
211  rodsLog(
212  LOG_DEBUG,
213  "load_plugin - loaded [%s]",
214  _plugin_name.c_str() );
215 
216  return SUCCESS();
217 
218  } // load_plugin
219 
220 }; // namespace irods
221 
222 
223 
224 #endif // __IRODS_LOAD_PLUGIN_HPP__
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
irods_configuration_keywords.hpp
getRodsEnv
int getRodsEnv(rodsEnv *myRodsEnv)
Definition: getRodsEnv.cpp:112
irods::plugin_name_generator
Definition: irods_plugin_name_generator.hpp:15
PASS
#define PASS(prev_error_)
Definition: irods_error.hpp:118
irods_exception.hpp
env
Definition: restructs.hpp:226
irods::experimental::administration::client::v1::exists
auto exists(rcComm_t &conn, const user &user) -> bool
Definition: user_administration.cpp:359
pid_age.p
p
Definition: pid_age.py:13
irods_default_paths.hpp
irods::load_plugin
error load_plugin(PluginType *&_plugin, const std::string &_plugin_name, const std::string &_interface, const std::string &_instance_name, const Ts &... _args)
Definition: irods_load_plugin.hpp:126
PASSMSG
#define PASSMSG(message_, prev_error_)
Definition: irods_error.hpp:119
SYS_INVALID_INPUT_PARAM
@ SYS_INVALID_INPUT_PARAM
Definition: rodsErrorTable.h:195
PLUGIN_ERROR
@ PLUGIN_ERROR
Definition: rodsErrorTable.h:757
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
irods::resolve_plugin_path
static error resolve_plugin_path(const std::string &_type, std::string &_path)
Definition: irods_load_plugin.hpp:33
LOG_DEBUG
#define LOG_DEBUG
Definition: rodsLog.h:23
irods
Definition: apiHandler.hpp:35
terminate_irods_processes.e
e
Definition: terminate_irods_processes.py:19
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
irods::log
void log(const error &)
Definition: irods_log.cpp:13
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
irods::error
Definition: irods_error.hpp:23
irods_plugin_name_generator.hpp
PLUGIN_ERROR_MISSING_SHARED_OBJECT
@ PLUGIN_ERROR_MISSING_SHARED_OBJECT
Definition: rodsErrorTable.h:776
irods::exception
Definition: irods_exception.hpp:15
rodsErrorTable.h
irods::get_irods_default_plugin_directory
boost::filesystem::path get_irods_default_plugin_directory()
Definition: irods_default_paths.cpp:43
rodsEnv
Definition: getRodsEnv.h:8
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
irods_log.hpp
getRodsEnv.h