~drizzle-trunk/drizzle/development

1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2009 Sun Microsystems
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
20
#include "config.h"
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
21
22
#include <dlfcn.h>
23
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
24
#include <cerrno>
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
25
#include <string>
26
27
#include "drizzled/plugin.h"
28
#include "drizzled/definitions.h"
29
#include "drizzled/error.h"
30
#include "drizzled/errmsg_print.h"
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
31
#include "drizzled/module/library.h"
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
32
33
using namespace std;
34
35
namespace drizzled
36
{
37
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
38
module::Library::Library(const std::string &name_arg,
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
39
                         void *handle_arg,
40
                         const Manifest *manifest_arg)
41
 : name(name_arg), handle(handle_arg), manifest(manifest_arg)
42
{}
43
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
44
module::Library::~Library()
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
45
{
1458.1.1 by mordred
Removed dlclose() call to fix valgrind output.
46
  /**
47
   * @TODO: This breaks valgrind at the moment. 
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
48
  if (handle)
49
    dlclose(handle);
1458.1.1 by mordred
Removed dlclose() call to fix valgrind output.
50
  */
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
51
}
52
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
53
const string module::Library::getLibraryPath(const string &plugin_name)
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
54
{
55
  /* Compile dll path */
56
  string dlpath;
57
  dlpath.reserve(FN_REFLEN);
58
  dlpath.append(opt_plugin_dir);
59
  dlpath.append("/");
60
  dlpath.append("lib");
61
  dlpath.append(plugin_name);
1377.2.1 by Lu Guanqun
apply the patch to fix a problem on mac osx
62
  dlpath.append("_plugin");
63
#if defined(TARGET_OS_OSX)
64
  dlpath.append(".dylib");
65
#else
66
  dlpath.append(".so");
67
#endif
1530.2.3 by Monty Taylor
Changed the builtin plugin code path to work exactly the same as dynamic.
68
  return dlpath;
69
}
70
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
71
module::Library *module::Library::loadLibrary(const string &plugin_name, bool builtin)
1530.2.3 by Monty Taylor
Changed the builtin plugin code path to work exactly the same as dynamic.
72
{
73
  /*
74
    Ensure that the dll doesn't have a path.
75
    This is done to ensure that only approved libraries from the
76
    plugin directory are used (to make this even remotely secure).
77
  */
78
  size_t found= plugin_name.find(FN_LIBCHAR);
79
  if (found != string::npos)
80
  {
81
    errmsg_printf(ERRMSG_LVL_ERROR, "%s",ER(ER_PLUGIN_NO_PATHS));
82
    return NULL;
83
  }
84
85
  void *handle= NULL;
86
  string dlpath("");
87
88
  if (builtin)
89
  {
90
    dlpath.assign("<builtin>");
1666.4.11 by Monty Taylor
Changed flag to local so that plugin conflict will hit before symbol
91
    handle= dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
1530.2.3 by Monty Taylor
Changed the builtin plugin code path to work exactly the same as dynamic.
92
    if (handle == NULL)
93
    {
94
      const char *errmsg= dlerror();
95
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_OPEN_LIBRARY),
96
                    dlpath.c_str(), errno, errmsg);
97
      (void)dlerror();
98
99
      return NULL;
100
    }
101
  }
102
  else
103
  {
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
104
  /* Open new dll handle */
1530.2.3 by Monty Taylor
Changed the builtin plugin code path to work exactly the same as dynamic.
105
    dlpath.assign(Library::getLibraryPath(plugin_name));
106
    handle= dlopen(dlpath.c_str(), RTLD_NOW|RTLD_GLOBAL);
107
    if (handle == NULL)
108
    {
109
      const char *errmsg= dlerror();
110
      uint32_t dlpathlen= dlpath.length();
1530.2.4 by Monty Taylor
Fixed style catches from Jay.
111
      if (not dlpath.compare(0, dlpathlen, errmsg))
1530.2.3 by Monty Taylor
Changed the builtin plugin code path to work exactly the same as dynamic.
112
      { // if errmsg starts from dlpath, trim this prefix.
1530.2.4 by Monty Taylor
Fixed style catches from Jay.
113
        errmsg+= dlpathlen;
1530.2.3 by Monty Taylor
Changed the builtin plugin code path to work exactly the same as dynamic.
114
        if (*errmsg == ':') errmsg++;
115
        if (*errmsg == ' ') errmsg++;
116
      }
117
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_OPEN_LIBRARY),
118
                    dlpath.c_str(), errno, errmsg);
119
1530.2.4 by Monty Taylor
Fixed style catches from Jay.
120
      // This, in theory, should cause dlerror() to deallocate the error
1530.2.3 by Monty Taylor
Changed the builtin plugin code path to work exactly the same as dynamic.
121
      // message. Found this via Google'ing :)
122
      (void)dlerror();
123
124
      return NULL;
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
125
    }
126
  }
127
1241.10.1 by Monty Taylor
Added ability to specify all of the meta information in the plugin.ini file. This allows us to have a streamlined out-of-tree build.
128
  string plugin_decl_sym("_drizzled_");
129
  plugin_decl_sym.append(plugin_name);
130
  plugin_decl_sym.append("_plugin_");
131
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
132
  /* Find plugin declarations */
1241.10.1 by Monty Taylor
Added ability to specify all of the meta information in the plugin.ini file. This allows us to have a streamlined out-of-tree build.
133
  void *sym= dlsym(handle, plugin_decl_sym.c_str());
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
134
  if (sym == NULL)
135
  {
136
    const char* errmsg= dlerror();
137
    errmsg_printf(ERRMSG_LVL_ERROR, errmsg);
138
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_FIND_DL_ENTRY),
1241.10.1 by Monty Taylor
Added ability to specify all of the meta information in the plugin.ini file. This allows us to have a streamlined out-of-tree build.
139
                  plugin_decl_sym.c_str(), dlpath.c_str());
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
140
    (void)dlerror();
141
    dlclose(handle);
142
    return NULL;
143
  }
144
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
145
  const Manifest *manifest= static_cast<module::Manifest *>(sym); 
1241.10.3 by Monty Taylor
Throw an error on invalid library version.
146
  if (manifest->drizzle_version != DRIZZLE_VERSION_ID)
147
  {
148
    errmsg_printf(ERRMSG_LVL_ERROR,
149
                  _("Plugin module %s was compiled for version %" PRIu64 ", "
150
                    "which does not match the current running version of "
151
                    "Drizzle: %" PRIu64"."),
152
                 dlpath.c_str(), manifest->drizzle_version,
153
                 DRIZZLE_VERSION_ID);
154
    return NULL;
155
  }
156
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
157
  return new (nothrow) module::Library(plugin_name, handle, manifest);
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
158
}
159
160
} /* namespace drizzled */