~drizzle-developers/ubuntu/karmic/drizzle/ppa

« back to all changes in this revision

Viewing changes to plugin/mysql_unix_socket_protocol/protocol.cc

  • Committer: Monty Taylor
  • Date: 2010-11-24 18:44:57 UTC
  • mfrom: (1308.1.31 trunk)
  • Revision ID: mordred@inaugust.com-20101124184457-qd6jvoe2wgnvl3yq
Tags: 2010.11.04-0ubuntu1~karmic1
* New upstream release.
* Turn off -Werror for packaging builds. (Closes: #602662)

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <algorithm>
31
31
#include <iostream>
32
32
#include <boost/program_options.hpp>
 
33
#include <boost/filesystem.hpp>
33
34
#include <drizzled/module/option_map.h>
34
35
 
35
36
#include <sys/un.h>
38
39
 
39
40
#define DRIZZLE_UNIX_SOCKET_PATH "/tmp/mysql.socket"
40
41
 
41
 
static std::string unix_socket_path(DRIZZLE_UNIX_SOCKET_PATH);
42
 
 
43
42
namespace po= boost::program_options;
 
43
namespace fs= boost::filesystem;
44
44
using namespace drizzled;
45
45
using namespace std;
46
46
 
47
47
namespace mysql_unix_socket_protocol
48
48
{
49
49
 
 
50
static bool clobber= false;
 
51
 
50
52
Protocol::~Protocol()
51
53
{
 
54
  fs::remove(unix_socket_path);
52
55
}
53
56
 
54
57
const char* Protocol::getHost(void) const
55
58
{
56
 
  return DRIZZLE_UNIX_SOCKET_PATH;
 
59
  return unix_socket_path.file_string().c_str();
57
60
}
58
61
 
59
62
in_port_t Protocol::getPort(void) const
65
68
{  
66
69
  const module::option_map &vm= context.getOptions();
67
70
 
68
 
  if (vm.count("path"))
69
 
  {
70
 
    unix_socket_path.clear();
71
 
    unix_socket_path.append(vm["path"].as<string>());
72
 
  }
73
 
 
74
 
  context.add(new Protocol("mysql_unix_socket_protocol", true));
 
71
  fs::path uds_path(vm["path"].as<fs::path>());
 
72
  if (not fs::exists(uds_path))
 
73
  {
 
74
    context.add(new Protocol("mysql_unix_socket_protocol",
 
75
                             true,
 
76
                             uds_path));
 
77
    context.registerVariable(new sys_var_const_string_val("path", fs::system_complete(uds_path).file_string()));
 
78
    context.registerVariable(new sys_var_bool_ptr_readonly("clobber", &clobber));
 
79
  }
 
80
  else
 
81
  {
 
82
    cerr << uds_path << _(" exists already. Do you have another Drizzle or "
 
83
                          "MySQL running? Or perhaps the file is stale and "
 
84
                          "should be removed?") << std::endl;
 
85
    return 0;
 
86
  }
75
87
 
76
88
  return 0;
77
89
}
78
90
 
79
91
bool Protocol::getFileDescriptors(std::vector<int> &fds)
80
92
{
81
 
  struct sockaddr_un servAddr;
82
 
  socklen_t addrlen;
83
93
  int unix_sock;
84
94
 
85
95
  if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
88
98
    return false;
89
99
  }
90
100
 
 
101
  // In case we restart and find something in our way we move it aside and
 
102
  // then attempt to remove it.
 
103
  if (clobber)
 
104
  {
 
105
    fs::path move_file(unix_socket_path.file_string() + ".old");
 
106
    fs::rename(unix_socket_path, move_file);
 
107
    unlink(move_file.file_string().c_str());
 
108
  }
 
109
 
 
110
 
 
111
  int arg= 1;
 
112
 
 
113
  (void) setsockopt(unix_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg));
 
114
  unlink(unix_socket_path.file_string().c_str());
 
115
 
 
116
  struct sockaddr_un servAddr;
91
117
  memset(&servAddr, 0, sizeof(servAddr));
92
118
 
93
119
  servAddr.sun_family= AF_UNIX;
94
 
  strcpy(servAddr.sun_path, unix_socket_path.c_str());
95
 
  (void) unlink(unix_socket_path.c_str());
96
 
 
97
 
  int arg= 1;
98
 
 
99
 
  (void) setsockopt(unix_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg));
100
 
 
101
 
  addrlen= sizeof(servAddr);
 
120
  if (unix_socket_path.file_string().size() > sizeof(servAddr.sun_path))
 
121
  {
 
122
    std::cerr << "Unix Socket Path length too long. Must be under "
 
123
      << sizeof(servAddr.sun_path) << " bytes." << endl;
 
124
    return false;
 
125
  }
 
126
  memcpy(servAddr.sun_path, unix_socket_path.file_string().c_str(), sizeof(servAddr.sun_path)-1);
 
127
 
 
128
  socklen_t addrlen= sizeof(servAddr);
102
129
  if (::bind(unix_sock, reinterpret_cast<sockaddr *>(&servAddr), addrlen) < 0)
103
130
  { 
104
 
    std::cerr << "Can't start server : Bind on unix socket\n";
105
 
    std::cerr << "Do you already have another of drizzled or mysqld running on socket: " << unix_socket_path << "?\n";
106
 
    std::cerr << "Can't start server : UNIX Socket";
 
131
    std::cerr << "Can't start server : Bind on unix socket." << std::endl;
 
132
    std::cerr << "Do you already have another of drizzled or mysqld running on socket: " << unix_socket_path << "?" << std::endl;
 
133
    std::cerr << "Can't start server : UNIX Socket" << std::endl;
107
134
 
108
135
    return false;
109
136
  }
110
137
 
111
 
  if (listen(unix_sock,(int) 1000) < 0)
 
138
  if (listen(unix_sock, (int) 1000) < 0)
112
139
  {
113
140
    std::cerr << "listen() on Unix socket failed with error " << errno << "\n";
114
141
  }
115
142
  else
116
143
  {
117
 
    std::cerr << "Listening on " << unix_socket_path.c_str() << "\n";
 
144
    std::cerr << "Listening on " << unix_socket_path << "\n";
118
145
  }
 
146
  (void) unlink(unix_socket_path.file_string().c_str());
119
147
 
120
148
  fds.push_back(unix_sock);
121
149
 
126
154
static void init_options(drizzled::module::option_context &context)
127
155
{
128
156
  context("path",
129
 
          po::value<string>()->default_value(unix_socket_path),
 
157
          po::value<fs::path>()->default_value(DRIZZLE_UNIX_SOCKET_PATH),
130
158
          N_("Path used for MySQL UNIX Socket Protocol."));
 
159
  context("clobber",
 
160
          N_("Clobber socket file if one is there already."));
 
161
 
131
162
}
132
163
 
133
 
static drizzle_sys_var* sys_variables[]= {
134
 
  NULL
135
 
};
136
 
 
137
164
} /* namespace mysql_unix_socket_protocol */
138
165
 
139
 
DRIZZLE_PLUGIN(mysql_unix_socket_protocol::init, mysql_unix_socket_protocol::sys_variables, mysql_unix_socket_protocol::init_options);
 
166
DRIZZLE_PLUGIN(mysql_unix_socket_protocol::init, NULL, mysql_unix_socket_protocol::init_options);