Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:15:42

0001 #ifndef __XRDSYSPLUGIN__
0002 #define __XRDSYSPLUGIN__
0003 /******************************************************************************/
0004 /*                                                                            */
0005 /*                       X r d S y s P l u g i n . h h                        */
0006 /*                                                                            */
0007 /* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University  */
0008 /*                            All Rights Reserved                             */
0009 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
0010 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
0011 /*                                                                            */
0012 /* This file is part of the XRootD software suite.                            */
0013 /*                                                                            */
0014 /* XRootD is free software: you can redistribute it and/or modify it under    */
0015 /* the terms of the GNU Lesser General Public License as published by the     */
0016 /* Free Software Foundation, either version 3 of the License, or (at your     */
0017 /* option) any later version.                                                 */
0018 /*                                                                            */
0019 /* XRootD is distributed in the hope that it will be useful, but WITHOUT      */
0020 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or      */
0021 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public       */
0022 /* License for more details.                                                  */
0023 /*                                                                            */
0024 /* You should have received a copy of the GNU Lesser General Public License   */
0025 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file  */
0026 /* COPYING (GPL license).  If not, see <http://www.gnu.org/licenses/>.        */
0027 /*                                                                            */
0028 /* The copyright holder's institutional names and contributor's names may not */
0029 /* be used to endorse or promote products derived from this software without  */
0030 /* specific prior written permission of the institution or contributor.       */
0031 /******************************************************************************/
0032   
0033 #include <cstring>
0034 
0035 struct XrdVersionInfo;
0036 
0037 class XrdSysError;
0038 
0039 //------------------------------------------------------------------------------
0040 //! Handy class to load run-time plugins and optionally check if the version
0041 //! is compatible with the caller's version number. Version numbers are defined
0042 //! as "aaa.bb.cc" where aaa is a decimnal major version, bb is a decimal minor
0043 //! version, and cc is the decimal patch version number. Only the major and,
0044 //! optionally, minor version numbers are checked. The checking rules are
0045 //! defined in XrdVersion.hh and are rather liberal in nature. In order to
0046 //! check versions, the plugin versioning rule must be defined in XrdVersion.hh
0047 //! and constructor #2 or #3 must be used. The symbolic name of the plugin's
0048 //! version information is the plugin symbol being looked up appended with
0049 //! "Version" and must be defined as an XrdVersionInfo structure.
0050 //------------------------------------------------------------------------------
0051 
0052 class XrdSysPlugin
0053 {
0054 public:
0055 
0056 //------------------------------------------------------------------------------
0057 //! Prepare shared library for use (optional call).
0058 //!
0059 //! @param  allMsgs  When true messages all messages are handled as directed by
0060 //!                  the constructor. Otherwise, only messages regarding ENOENT
0061 //!                  (file not found ) are suppressed.
0062 //! @param  global   when true then the symbols defined in the plug-in shared
0063 //!                  library are made available for symbol resolution of
0064 //!                  subsequently loaded libraries.
0065 //!
0066 //! @return !0       Library successfully prepared.
0067 //!         =0       Library cannot be prepared; if mBuff is supplied, it
0068 //!                  contains the error message. If the file was not found,
0069 //!                  errno is set to ENOENT; otherwise to ENOEXEC.
0070 //!
0071 //! @note   This method is implicitly called when calling getPlugin().
0072 //------------------------------------------------------------------------------
0073 
0074 void *getLibrary(bool allMsgs=true, bool global=false);
0075 
0076 //------------------------------------------------------------------------------
0077 //! Get the address of a plugin from a shared library, opening the plug-in
0078 //! shared library if not already open. Symbols in the library are local.
0079 //!
0080 //! @param  pname    the plug-in extern "C" symbolic name
0081 //! @param  optional when  0 then issue error message when symbol isn't found.
0082 //!                  Otherwise, the mising symbol is treated as an error.
0083 //!
0084 //! @return Success: the address of the symbol in the shared library/executable.
0085 //!                  The address becomes invalid when this object is deleted
0086 //!                  unless Persist() is called prior to deletion.
0087 //!         Failure: Null
0088 //------------------------------------------------------------------------------
0089 
0090 void *getPlugin(const char *pname, int optional=0);
0091 
0092 //------------------------------------------------------------------------------
0093 //! Get the address of a plugin from a shared library, opening the plug-in
0094 //! shared library if not already open and optionally make the symbols global.
0095 //!
0096 //! @param  pname    the plug-in extern "C" symbolic name
0097 //! @param  optional when  0 then issue error message when symbol isn't found.
0098 //!                  Otherwise, the mising symbol is treated as an error. When
0099 //!                  optional is greater than 1, the load message is suppressed.
0100 //! @param  global   when true then the symbols defined in the plug-in shared
0101 //!                  library are made available for symbol resolution of
0102 //!                  subsequently loaded libraries.
0103 //! @return Success: the address of the symbol in the shared library/executable.
0104 //!                  The address becomes invalid when this object is deleted
0105 //!                  unless Persist() is called prior to deletion.
0106 //!         Failure: Null
0107 //------------------------------------------------------------------------------
0108 
0109 void *getPlugin(const char *pname, int optional, bool global);
0110 
0111 //------------------------------------------------------------------------------
0112 //! Make library persistent even when the plugin object is deleted. Note that
0113 //! if getPlugin() is called afterwards, the library will be re-opened!
0114 //!
0115 //! @return pointer to the opened shared library.
0116 //------------------------------------------------------------------------------
0117 
0118 void *Persist() {void *lHan = libHandle; libHandle = 0; return lHan;}
0119 
0120 //------------------------------------------------------------------------------
0121 //! Preload a shared library. This method is meant for those threading models
0122 //! that require libraries to be opened in the main thread (e.g. MacOS). This
0123 //! method is meant to be called before therads start and is not thread-safe.
0124 //!
0125 //! @param  path     -> to the library path, typically this should just be the
0126 //!                     library filename so that LD_LIBRARY_PATH is used to
0127 //!                     discover the directory path. This allows getPlugin()
0128 //!                     to properly match preloaded libraries.
0129 //! @param  ebuff    -> buffer where eror message is to be placed. The message
0130 //!                     will always end with a null byte. If no error buffer
0131 //!                     is supplied, any error messages are discarded.
0132 //! @param  eblen    -> length of the supplied buffer, eBuff.
0133 //!
0134 //! @return True      The library was preloaded.
0135 //!         False     The library could not be preloaded, ebuff, if supplied,
0136 //!                   contains the error message text.
0137 //------------------------------------------------------------------------------
0138 
0139 static
0140 bool  Preload(const char *path,  char *ebuff=0, int eblen=0);
0141 
0142 //------------------------------------------------------------------------------
0143 //! Compare two versions for compatibility, optionally printing a warning.
0144 //!
0145 //! @param  vInf1 -> Version information for source.
0146 //! @param  vInf2 -> Version information for target.
0147 //! @param  noMsg -> If true, no error messages are written to stderr.
0148 //!
0149 //! @return True if versions are compatible (i.e. major and minor versions are
0150 //!         identical as required for locally linked code); false otherwise.
0151 //------------------------------------------------------------------------------
0152 
0153 static
0154 bool  VerCmp(XrdVersionInfo &vInf1, XrdVersionInfo &vInf2, bool noMsg=false);
0155 
0156 //------------------------------------------------------------------------------
0157 //! Constructor #1 (version number checking is not to be performed)
0158 //!
0159 //! @param  erp      -> error message object to display error messages.
0160 //! @param  path     -> path to the shared library containing a plug-in. If NULL
0161 //!                     the the executable image is searched for the plug-in.
0162 //!                     Storage must persist while this object is alive.
0163 //------------------------------------------------------------------------------
0164 
0165       XrdSysPlugin(XrdSysError *erp, const char *path)
0166                   : eDest(erp), libName(0), libPath(path ? strdup(path) : 0),
0167                     libHandle(0), myInfo(0), eBuff(0), eBLen(0), msgCnt(-1) {}
0168 
0169 //------------------------------------------------------------------------------
0170 //! Constructor #2 (version number checking may be performed)
0171 //!
0172 //! @param  erp      -> error message object to display error messages.
0173 //! @param  path     -> path to the shared library containing a plug-in. If NULL
0174 //!                     the the executable image is searched for the plug-in.
0175 //!                     Storage must persist while this object is alive.
0176 //! @param  lname    -> logical name of the plugin library (e.g. osslib) to be
0177 //!                     used in any error messages.
0178 //!                     Storage must persist while this object is alive.
0179 //! @param  vinf     -> permanent version information of the plug-in loader.
0180 //!                     If zero, then no version checking is performed.
0181 //! @param  msgNum   -> Number of times getPlugin() is to produce a version
0182 //!                     message for a loaded plugin. The default is always.
0183 //------------------------------------------------------------------------------
0184 
0185       XrdSysPlugin(XrdSysError *erp, const char *path, const char *lname,
0186                    XrdVersionInfo *vinf=0, int msgNum=-1)
0187                   : eDest(erp), libName(lname),
0188                     libPath(path ? strdup(path) : 0), libHandle(0),
0189                     myInfo(vinf), eBuff(0), eBLen(0), msgCnt(msgNum) {}
0190 
0191 //------------------------------------------------------------------------------
0192 //! Constructor #3 (version number checking may be performed and any error
0193 //!                 is returned in a supplied buffer)
0194 //!
0195 //! @param  ebuff    -> buffer where eror message is to be placed. The message
0196 //!                     will always end with a null byte.
0197 //! @param  eblen    -> length of the supplied buffer, eBuff.
0198 //! @param  path     -> path to the shared library containing a plug-in. If NULL
0199 //!                     the the executable image is searched for the plug-in.
0200 //!                     Storage must persist while this object is alive.
0201 //! @param  lname    -> logical name of the plugin library (e.g. osslib) to be
0202 //!                     used in any error messages.
0203 //!                     Storage must persist while this object is alive.
0204 //! @param  vinf     -> permanent version information of the plug-in loader.
0205 //!                     If Zero, then no version checking is performed.
0206 //! @param  msgNum   -> Number of times getPlugin() is to produce a version
0207 //!                     message for a loaded plugin. The default is always.
0208 //------------------------------------------------------------------------------
0209 
0210       XrdSysPlugin(char *ebuff, int eblen, const char *path, const char *lname,
0211                    XrdVersionInfo *vinf=0, int msgNum=-1)
0212                   : eDest(0), libName(lname),
0213                     libPath(path ? strdup(path) : 0), libHandle(0),
0214                     myInfo(vinf), eBuff(ebuff), eBLen(eblen), msgCnt(msgNum) {}
0215 
0216 //------------------------------------------------------------------------------
0217 //! Destructor
0218 //------------------------------------------------------------------------------
0219 
0220      ~XrdSysPlugin();
0221 
0222 private:
0223 enum            cvResult {cvBad = 0, cvNone, cvMissing, cvClean, cvDirty};
0224 
0225 cvResult        badVersion(XrdVersionInfo &urInfo,char mmv,int majv,int minv);
0226 cvResult        chkVersion(XrdVersionInfo &urInfo, const char *pname, void *lh);
0227 static int      DLflags();
0228 static void    *Find(const char *libname);
0229 void            Inform(const char *txt1,   const char *txt2=0, const char *txt3=0,
0230                        const char *txt4=0, const char *txt5=0, int noHush=0);
0231 cvResult        libMsg(const char *txt1, const char *txt2, const char *mSym=0);
0232 const char     *msgSuffix(const char *Word, char *buff, int bsz);
0233 
0234 XrdSysError    *eDest;
0235 const char     *libName;
0236 char           *libPath;
0237 void           *libHandle;
0238 XrdVersionInfo *myInfo;
0239 char           *eBuff;
0240 int             eBLen;
0241 int             msgCnt;
0242 
0243 struct PLlist {PLlist  *next;
0244                char    *libPath;
0245                void    *libHandle;
0246               };
0247 
0248 static PLlist *plList;
0249 };
0250 #endif