~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/library.cc

  • Committer: Brian Aker
  • Date: 2010-01-22 00:53:13 UTC
  • Revision ID: brian@gaz-20100122005313-jmizcbcdi1lt4tcx
Revert db patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2009 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
 
20
#include "config.h"
21
21
 
22
22
#include <dlfcn.h>
23
23
 
24
24
#include <cerrno>
25
25
#include <string>
26
26
 
27
 
#include <boost/filesystem.hpp>
28
 
 
29
 
#include <drizzled/plugin.h>
30
 
#include <drizzled/definitions.h>
31
 
#include <drizzled/error.h>
32
 
#include <drizzled/errmsg_print.h>
33
 
#include <drizzled/module/library.h>
 
27
#include "drizzled/plugin.h"
 
28
#include "drizzled/definitions.h"
 
29
#include "drizzled/error.h"
 
30
#include "drizzled/errmsg_print.h"
 
31
#include "drizzled/plugin/library.h"
34
32
 
35
33
using namespace std;
36
 
namespace fs=boost::filesystem;
37
34
 
38
35
namespace drizzled
39
36
{
40
37
 
41
 
module::Library::Library(const std::string &name_arg,
 
38
plugin::Library::Library(const std::string &name_arg,
42
39
                         void *handle_arg,
43
40
                         const Manifest *manifest_arg)
44
41
 : name(name_arg), handle(handle_arg), manifest(manifest_arg)
45
42
{}
46
43
 
47
 
module::Library::~Library()
 
44
plugin::Library::~Library()
48
45
{
49
 
  /**
50
 
   * @TODO: This breaks valgrind at the moment. 
51
46
  if (handle)
52
47
    dlclose(handle);
53
 
  */
54
 
}
55
 
 
56
 
const fs::path module::Library::getLibraryPath(const string &plugin_name)
57
 
{
58
 
  string plugin_lib_name("lib");
59
 
  plugin_lib_name.append(plugin_name);
60
 
  plugin_lib_name.append("_plugin");
61
 
#if defined(TARGET_OS_OSX)
62
 
  plugin_lib_name.append(".dylib");
63
 
#else
64
 
  plugin_lib_name.append(".so");
65
 
#endif
66
 
 
67
 
  /* Compile dll path */
68
 
  return plugin_dir / plugin_lib_name;
69
 
}
70
 
 
71
 
module::Library *module::Library::loadLibrary(const string &plugin_name, bool builtin)
 
48
}
 
49
 
 
50
plugin::Library *plugin::Library::loadLibrary(const string &plugin_name)
72
51
{
73
52
  /*
74
53
    Ensure that the dll doesn't have a path.
78
57
  size_t found= plugin_name.find(FN_LIBCHAR);
79
58
  if (found != string::npos)
80
59
  {
81
 
    errmsg_printf(error::ERROR, "%s",ER(ER_PLUGIN_NO_PATHS));
 
60
    errmsg_printf(ERRMSG_LVL_ERROR, "%s",ER(ER_PLUGIN_NO_PATHS));
82
61
    return NULL;
83
62
  }
84
63
 
85
 
  void *dl_handle= NULL;
86
 
  string dlpath("");
87
 
 
88
 
  if (builtin)
89
 
  {
90
 
    dlpath.assign("<builtin>");
91
 
    dl_handle= dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
92
 
    if (dl_handle == NULL)
93
 
    {
94
 
      const char *errmsg= dlerror();
95
 
      errmsg_printf(error::ERROR, ER(ER_CANT_OPEN_LIBRARY),
96
 
                    dlpath.c_str(), errno, errmsg);
97
 
      (void)dlerror();
98
 
 
99
 
      return NULL;
100
 
    }
101
 
  }
102
 
  else
103
 
  {
 
64
  /* Compile dll path */
 
65
  string dlpath;
 
66
  dlpath.reserve(FN_REFLEN);
 
67
  dlpath.append(opt_plugin_dir);
 
68
  dlpath.append("/");
 
69
  dlpath.append("lib");
 
70
  dlpath.append(plugin_name);
 
71
  dlpath.append("_plugin.so");
 
72
 
104
73
  /* Open new dll handle */
105
 
    dlpath.assign(Library::getLibraryPath(plugin_name).file_string());
106
 
    dl_handle= dlopen(dlpath.c_str(), RTLD_NOW|RTLD_GLOBAL);
107
 
    if (dl_handle == NULL)
108
 
    {
109
 
      const char *errmsg= dlerror();
110
 
      uint32_t dlpathlen= dlpath.length();
111
 
      if (not dlpath.compare(0, dlpathlen, errmsg))
112
 
      { // if errmsg starts from dlpath, trim this prefix.
113
 
        errmsg+= dlpathlen;
114
 
        if (*errmsg == ':') errmsg++;
115
 
        if (*errmsg == ' ') errmsg++;
116
 
      }
117
 
      errmsg_printf(error::ERROR, ER(ER_CANT_OPEN_LIBRARY),
118
 
                    dlpath.c_str(), errno, errmsg);
119
 
 
120
 
      // This, in theory, should cause dlerror() to deallocate the error
121
 
      // message. Found this via Google'ing :)
122
 
      (void)dlerror();
123
 
 
124
 
      return NULL;
 
74
  void *handle= dlopen(dlpath.c_str(), RTLD_NOW|RTLD_GLOBAL);
 
75
  if (handle == NULL)
 
76
  {
 
77
    const char *errmsg= dlerror();
 
78
    uint32_t dlpathlen= dlpath.length();
 
79
    if (!dlpath.compare(0, dlpathlen, errmsg))
 
80
    { // if errmsg starts from dlpath, trim this prefix.
 
81
      errmsg+=dlpathlen;
 
82
      if (*errmsg == ':') errmsg++;
 
83
      if (*errmsg == ' ') errmsg++;
125
84
    }
 
85
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_OPEN_LIBRARY),
 
86
                  dlpath.c_str(), errno, errmsg);
 
87
 
 
88
    // This is, in theory, should cause dlerror() to deallocate the error
 
89
    // message. Found this via Google'ing :)
 
90
    (void)dlerror();
 
91
 
 
92
    return NULL;
126
93
  }
127
94
 
 
95
 
128
96
  string plugin_decl_sym("_drizzled_");
129
97
  plugin_decl_sym.append(plugin_name);
130
98
  plugin_decl_sym.append("_plugin_");
131
99
 
132
100
  /* Find plugin declarations */
133
 
  void *sym= dlsym(dl_handle, plugin_decl_sym.c_str());
 
101
  void *sym= dlsym(handle, plugin_decl_sym.c_str());
134
102
  if (sym == NULL)
135
103
  {
136
104
    const char* errmsg= dlerror();
137
 
    errmsg_printf(error::ERROR, errmsg);
138
 
    errmsg_printf(error::ERROR, ER(ER_CANT_FIND_DL_ENTRY),
 
105
    errmsg_printf(ERRMSG_LVL_ERROR, errmsg);
 
106
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_FIND_DL_ENTRY),
139
107
                  plugin_decl_sym.c_str(), dlpath.c_str());
140
108
    (void)dlerror();
141
 
    dlclose(dl_handle);
 
109
    dlclose(handle);
142
110
    return NULL;
143
111
  }
144
112
 
145
 
  const Manifest *module_manifest= static_cast<module::Manifest *>(sym); 
146
 
  if (module_manifest->drizzle_version != DRIZZLE_VERSION_ID)
 
113
  const Manifest *manifest= static_cast<plugin::Manifest *>(sym); 
 
114
  if (manifest->drizzle_version != DRIZZLE_VERSION_ID)
147
115
  {
148
 
    errmsg_printf(error::ERROR,
 
116
    errmsg_printf(ERRMSG_LVL_ERROR,
149
117
                  _("Plugin module %s was compiled for version %" PRIu64 ", "
150
118
                    "which does not match the current running version of "
151
119
                    "Drizzle: %" PRIu64"."),
152
 
                 dlpath.c_str(), module_manifest->drizzle_version,
153
 
                 static_cast<uint64_t>(DRIZZLE_VERSION_ID));
 
120
                 dlpath.c_str(), manifest->drizzle_version,
 
121
                 DRIZZLE_VERSION_ID);
154
122
    return NULL;
155
123
  }
156
124
 
157
 
  return new (nothrow) module::Library(plugin_name, dl_handle, module_manifest);
 
125
  return new (nothrow) plugin::Library(plugin_name, handle, manifest);
158
126
}
159
127
 
160
128
} /* namespace drizzled */