summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorStephen D. Huston <shuston@apache.org>2008-10-09 15:20:49 +0000
committerStephen D. Huston <shuston@apache.org>2008-10-09 15:20:49 +0000
commit0b195851725cd2b0982d26a108e7239eca6b2052 (patch)
tree0eeaa66dc3daa0147c92995cda6b0f014ac8c512 /cpp/src
parentbfa255f4fd7a67f1433b424913515633d7e58c2f (diff)
downloadqpid-python-0b195851725cd2b0982d26a108e7239eca6b2052.tar.gz
Make Address/TcpAddress manipulation portable; extend SystemInfo functions to Windows; resolves QPID-1325
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@703179 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Makefile.am3
-rwxr-xr-xcpp/src/qpid/Address.h53
-rw-r--r--cpp/src/qpid/Url.cpp30
-rw-r--r--cpp/src/qpid/Url.h23
-rw-r--r--cpp/src/qpid/broker/System.cpp22
-rw-r--r--cpp/src/qpid/sys/SystemInfo.cpp35
-rw-r--r--cpp/src/qpid/sys/SystemInfo.h38
-rwxr-xr-xcpp/src/qpid/sys/posix/SystemInfo.cpp95
-rwxr-xr-xcpp/src/qpid/sys/windows/SystemInfo.cpp160
9 files changed, 360 insertions, 99 deletions
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am
index 9486d7a8b9..149c1d91e6 100644
--- a/cpp/src/Makefile.am
+++ b/cpp/src/Makefile.am
@@ -76,6 +76,7 @@ posix_plat_src = \
qpid/sys/posix/Time.cpp \
qpid/sys/posix/Thread.cpp \
qpid/sys/posix/Shlib.cpp \
+ qpid/sys/posix/SystemInfo.cpp \
qpid/sys/posix/Mutex.cpp \
qpid/sys/posix/Fork.cpp \
qpid/sys/posix/StrError.cpp \
@@ -273,7 +274,6 @@ libqpidcommon_la_SOURCES = \
qpid/sys/PollableCondition.h \
qpid/sys/PollableQueue.h \
qpid/sys/Runnable.cpp \
- qpid/sys/SystemInfo.cpp \
qpid/sys/Shlib.cpp \
qpid/DataDir.cpp \
qpid/Options.cpp \
@@ -398,6 +398,7 @@ nobase_include_HEADERS = \
$(platform_hdr) \
qpid/amqp_0_10/apply.h \
qpid/assert.h \
+ qpid/Address.h \
qpid/DataDir.h \
qpid/Exception.h \
qpid/sys/ExceptionHolder.h \
diff --git a/cpp/src/qpid/Address.h b/cpp/src/qpid/Address.h
new file mode 100755
index 0000000000..2c4c16993d
--- /dev/null
+++ b/cpp/src/qpid/Address.h
@@ -0,0 +1,53 @@
+#ifndef QPID_ADDRESS_H
+#define QPID_ADDRESS_H
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "qpid/sys/IntegerTypes.h"
+
+#include <boost/variant.hpp>
+#include <string>
+#include <vector>
+
+namespace qpid {
+
+/** TCP address of a broker - host:port */
+struct TcpAddress {
+ static const uint16_t DEFAULT_PORT=5672;
+ explicit TcpAddress(const std::string& host_=std::string(),
+ uint16_t port_=DEFAULT_PORT)
+ : host(host_), port(port_) {}
+ std::string host;
+ uint16_t port;
+};
+
+inline bool operator==(const TcpAddress& x, const TcpAddress& y) {
+ return y.host==x.host && y.port == x.port;
+}
+
+/** Address is a variant of all address types, more coming in future. */
+struct Address : public boost::variant<TcpAddress> {
+ template <class T> Address(const T& t) : boost::variant<TcpAddress>(t) {}
+ template <class T> T* get() { return boost::get<T>(this); }
+ template <class T> const T* get() const { return boost::get<T>(this); }
+};
+
+} // namespace qpid
+
+#endif /*!QPID_ADDRESS_H*/
diff --git a/cpp/src/qpid/Url.cpp b/cpp/src/qpid/Url.cpp
index 95d6a34136..422939fdf4 100644
--- a/cpp/src/qpid/Url.cpp
+++ b/cpp/src/qpid/Url.cpp
@@ -19,6 +19,8 @@
#include "qpid/Url.h"
#include "qpid/Exception.h"
#include "qpid/Msg.h"
+#include "qpid/sys/SystemInfo.h"
+#include "qpid/sys/StrError.h"
#include <limits.h> // NB: must be before boost/spirit headers.
#include <boost/spirit.hpp>
@@ -26,10 +28,6 @@
#include <sstream>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <unistd.h>
-#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
@@ -45,31 +43,15 @@ std::ostream& operator<<(std::ostream& os, const TcpAddress& a) {
std::istream& operator>>(std::istream&, const TcpAddress&);
Url Url::getHostNameUrl(uint16_t port) {
- char name[HOST_NAME_MAX];
- if (::gethostname(name, sizeof(name)) != 0)
+ TcpAddress address("", port);
+ if (!sys::SystemInfo::getLocalHostname(address))
throw InvalidUrl(QPID_MSG("Cannot get host name: " << qpid::sys::strError(errno)));
- return Url(TcpAddress(name, port));
+ return Url(address);
}
-static const string LOCALHOST("127.0.0.1");
-
Url Url::getIpAddressesUrl(uint16_t port) {
Url url;
- int s = socket (PF_INET, SOCK_STREAM, 0);
- for (int i=1;;i++) {
- struct ifreq ifr;
- ifr.ifr_ifindex = i;
- if (::ioctl (s, SIOCGIFNAME, &ifr) < 0)
- break;
- /* now ifr.ifr_name is set */
- if (::ioctl (s, SIOCGIFADDR, &ifr) < 0)
- continue;
- struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;
- string addr(inet_ntoa(sin->sin_addr));
- if (addr != LOCALHOST)
- url.push_back(TcpAddress(addr, port));
- }
- close (s);
+ sys::SystemInfo::getLocalIpAddresses(port, url);
return url;
}
diff --git a/cpp/src/qpid/Url.h b/cpp/src/qpid/Url.h
index 67c8a861aa..0946b97490 100644
--- a/cpp/src/qpid/Url.h
+++ b/cpp/src/qpid/Url.h
@@ -19,8 +19,8 @@
*
*/
+#include "qpid/Address.h"
#include "qpid/Exception.h"
-#include <boost/variant.hpp>
#include <string>
#include <vector>
#include <new>
@@ -28,29 +28,8 @@
namespace qpid {
-/** TCP address of a broker - host:port */
-struct TcpAddress {
- static const uint16_t DEFAULT_PORT=5672;
- explicit TcpAddress(const std::string& host_=std::string(),
- uint16_t port_=DEFAULT_PORT)
- : host(host_), port(port_) {}
- std::string host;
- uint16_t port;
-};
-
-inline bool operator==(const TcpAddress& x, const TcpAddress& y) {
- return y.host==x.host && y.port == x.port;
-}
-
std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
-/** Address is a variant of all address types, more coming in future. */
-struct Address : public boost::variant<TcpAddress> {
- template <class T> Address(const T& t) : boost::variant<TcpAddress>(t) {}
- template <class T> T* get() { return boost::get<T>(this); }
- template <class T> const T* get() const { return boost::get<T>(this); }
-};
-
/** An AMQP URL contains a list of addresses */
struct Url : public std::vector<Address> {
diff --git a/cpp/src/qpid/broker/System.cpp b/cpp/src/qpid/broker/System.cpp
index 7b5e843e90..a11ad25bbe 100644
--- a/cpp/src/qpid/broker/System.cpp
+++ b/cpp/src/qpid/broker/System.cpp
@@ -20,7 +20,7 @@
#include "System.h"
#include "qpid/agent/ManagementAgent.h"
#include "qpid/framing/Uuid.h"
-#include <sys/utsname.h>
+#include "qpid/sys/SystemInfo.h"
#include <iostream>
#include <fstream>
@@ -64,15 +64,17 @@ System::System (string _dataDir) : mgmtObject(0)
}
mgmtObject = new _qmf::System (agent, this, systemId);
- struct utsname _uname;
- if (uname (&_uname) == 0)
- {
- mgmtObject->set_osName (std::string (_uname.sysname));
- mgmtObject->set_nodeName (std::string (_uname.nodename));
- mgmtObject->set_release (std::string (_uname.release));
- mgmtObject->set_version (std::string (_uname.version));
- mgmtObject->set_machine (std::string (_uname.machine));
- }
+ std::string sysname, nodename, release, version, machine;
+ qpid::sys::SystemInfo::getSystemId (sysname,
+ nodename,
+ release,
+ version,
+ machine);
+ mgmtObject->set_osName (sysname);
+ mgmtObject->set_nodeName (nodename);
+ mgmtObject->set_release (release);
+ mgmtObject->set_version (version);
+ mgmtObject->set_machine (machine);
agent->addObject (mgmtObject, 0x1000000000000001LL);
}
diff --git a/cpp/src/qpid/sys/SystemInfo.cpp b/cpp/src/qpid/sys/SystemInfo.cpp
deleted file mode 100644
index dcc7ad9985..0000000000
--- a/cpp/src/qpid/sys/SystemInfo.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "SystemInfo.h"
-#include <unistd.h>
-
-namespace qpid {
-namespace sys {
-
-long SystemInfo::concurrency() {
-#ifdef _SC_NPROCESSORS_ONLN // Linux specific.
- return sysconf(_SC_NPROCESSORS_ONLN);
-#else
- return -1;
-#endif
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/SystemInfo.h b/cpp/src/qpid/sys/SystemInfo.h
index 73c3ca3c17..5a116cf8ee 100644
--- a/cpp/src/qpid/sys/SystemInfo.h
+++ b/cpp/src/qpid/sys/SystemInfo.h
@@ -21,6 +21,9 @@
*
*/
+#include "qpid/sys/IntegerTypes.h"
+#include "qpid/Address.h"
+
namespace qpid {
namespace sys {
@@ -28,17 +31,38 @@ namespace sys {
* Retrieve information about the system we are running on.
* Results may be dependent on OS/hardware.
*/
-class SystemInfo
-{
- public:
- /** Estimate available concurrency, e.g. number of CPU cores.
+namespace SystemInfo {
+ /**
+ * Estimate available concurrency, e.g. number of CPU cores.
* -1 means estimate not available on this platform.
*/
- static long concurrency();
-};
+ long concurrency();
+
+ /**
+ * Get the local host name and set it in the specified TcpAddress.
+ * Returns false if it can't be obtained and sets errno to any error value.
+ */
+ bool getLocalHostname (TcpAddress &address);
-}} // namespace qpid::sys
+ void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList);
+ /**
+ * Retrieve system identifiers and versions. This is information that can
+ * generally be retrieved via POSIX uname().
+ *
+ * @param osName Receives the OS name; e.g., GNU/Linux or Windows
+ * @param nodeName Receives the nodename. This may or may not match the
+ * set hostname from getLocalHostname().
+ * @param release Receives the OS release identifier.
+ * @param version Receives the OS release version (kernel, build, sp, etc.)
+ * @param machine Receives the hardware type.
+ */
+ void getSystemId (std::string &osName,
+ std::string &nodeName,
+ std::string &release,
+ std::string &version,
+ std::string &machine);
+}}} // namespace qpid::sys::SystemInfo
#endif /*!QPID_SYS_SYSTEMINFO_H*/
diff --git a/cpp/src/qpid/sys/posix/SystemInfo.cpp b/cpp/src/qpid/sys/posix/SystemInfo.cpp
new file mode 100755
index 0000000000..c054931a96
--- /dev/null
+++ b/cpp/src/qpid/sys/posix/SystemInfo.cpp
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "qpid/sys/SystemInfo.h"
+
+#include <sys/ioctl.h>
+#include <sys/utsname.h>
+#include <net/if.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifndef HOST_NAME_MAX
+# define HOST_NAME_MAX 256
+#endif
+
+using namespace std;
+
+namespace qpid {
+namespace sys {
+
+long SystemInfo::concurrency() {
+#ifdef _SC_NPROCESSORS_ONLN // Linux specific.
+ return sysconf(_SC_NPROCESSORS_ONLN);
+#else
+ return -1;
+#endif
+}
+
+bool SystemInfo::getLocalHostname (TcpAddress &address) {
+ char name[HOST_NAME_MAX];
+ if (::gethostname(name, sizeof(name)) != 0)
+ return false;
+ address.host = name;
+ return true;
+}
+
+void SystemInfo::getLocalIpAddresses (uint16_t port,
+ std::vector<Address> &addrList) {
+
+ static const string LOCALHOST("127.0.0.1");
+
+ int s = socket (PF_INET, SOCK_STREAM, 0);
+ for (int i=1;;i++) {
+ struct ifreq ifr;
+ ifr.ifr_ifindex = i;
+ if (::ioctl (s, SIOCGIFNAME, &ifr) < 0)
+ break;
+ /* now ifr.ifr_name is set */
+ if (::ioctl (s, SIOCGIFADDR, &ifr) < 0)
+ continue;
+ struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;
+ string addr(inet_ntoa(sin->sin_addr));
+ if (addr != LOCALHOST)
+ addrList.push_back(TcpAddress(addr, port));
+ }
+ close (s);
+}
+
+void SystemInfo::getSystemId (std::string &osName,
+ std::string &nodeName,
+ std::string &release,
+ std::string &version,
+ std::string &machine)
+{
+ struct utsname _uname;
+ if (uname (&_uname) == 0)
+ {
+ osName = _uname.sysname;
+ nodeName = _uname.nodename;
+ release = _uname.release;
+ version = _uname.version;
+ machine = _uname.machine;
+ }
+}
+
+}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/windows/SystemInfo.cpp b/cpp/src/qpid/sys/windows/SystemInfo.cpp
new file mode 100755
index 0000000000..b887cac58b
--- /dev/null
+++ b/cpp/src/qpid/sys/windows/SystemInfo.cpp
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/* GetNativeSystemInfo call requires _WIN32_WINNT 0x0501 or higher */
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0501
+#endif
+
+#include "qpid/sys/IntegerTypes.h"
+#include "qpid/sys/SystemInfo.h"
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+
+#ifndef HOST_NAME_MAX
+# define HOST_NAME_MAX 256
+#endif
+
+namespace qpid {
+namespace sys {
+
+long SystemInfo::concurrency() {
+ SYSTEM_INFO sys_info;
+ ::GetSystemInfo (&sys_info);
+ long activeProcessors = 0;
+ DWORD_PTR mask = sys_info.dwActiveProcessorMask;
+ while (mask != 0) {
+ if (mask & 1)
+ ++activeProcessors;
+ mask >>= 1;
+ }
+ return activeProcessors;
+}
+
+bool SystemInfo::getLocalHostname (TcpAddress &address) {
+ char name[HOST_NAME_MAX];
+ if (::gethostname(name, sizeof(name)) != 0) {
+ errno = WSAGetLastError();
+ return false;
+ }
+ address.host = name;
+ return true;
+}
+
+void SystemInfo::getLocalIpAddresses (uint16_t port,
+ std::vector<Address> &addrList) {
+ enum { MAX_URL_INTERFACES = 100 };
+ static const std::string LOCALHOST("127.0.0.1");
+
+ SOCKET s = socket (PF_INET, SOCK_STREAM, 0);
+ if (s != INVALID_SOCKET) {
+ INTERFACE_INFO interfaces[MAX_URL_INTERFACES];
+ DWORD filledBytes = 0;
+ WSAIoctl (s,
+ SIO_GET_INTERFACE_LIST,
+ 0,
+ 0,
+ interfaces,
+ sizeof (interfaces),
+ &filledBytes,
+ 0,
+ 0);
+ unsigned int interfaceCount = filledBytes / sizeof (INTERFACE_INFO);
+ for (unsigned int i = 0; i < interfaceCount; ++i) {
+ if (interfaces[i].iiFlags & IFF_UP) {
+ std::string addr(inet_ntoa(interfaces[i].iiAddress.AddressIn.sin_addr));
+ if (addr != LOCALHOST)
+ addrList.push_back(TcpAddress(addr, port));
+ }
+ }
+ closesocket (s);
+ }
+}
+
+void SystemInfo::getSystemId (std::string &osName,
+ std::string &nodeName,
+ std::string &release,
+ std::string &version,
+ std::string &machine)
+{
+ osName = "Microsoft Windows";
+
+ char node[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD nodelen = MAX_COMPUTERNAME_LENGTH + 1;
+ GetComputerName (node, &nodelen);
+ nodeName = node;
+
+ OSVERSIONINFOEX vinfo;
+ vinfo.dwOSVersionInfoSize = sizeof(vinfo);
+ GetVersionEx ((OSVERSIONINFO *)&vinfo);
+
+ SYSTEM_INFO sinfo;
+ GetNativeSystemInfo(&sinfo);
+
+ switch(vinfo.dwMajorVersion) {
+ case 5:
+ switch(vinfo.dwMinorVersion) {
+ case 0:
+ release ="2000";
+ break;
+ case 1:
+ release = "XP";
+ break;
+ case 2:
+ if (sinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
+ sinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
+ release = "XP-64";
+ else
+ release = "Server 2003";
+ break;
+ default:
+ release = "Windows";
+ }
+ break;
+ case 6:
+ if (vinfo.wProductType == VER_NT_SERVER)
+ release = "Server 2008";
+ else
+ release = "Vista";
+ break;
+ default:
+ release = "Microsoft Windows";
+ }
+ version = vinfo.szCSDVersion;
+
+ switch(sinfo.wProcessorArchitecture) {
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ machine = "x86-64";
+ break;
+ case PROCESSOR_ARCHITECTURE_IA64:
+ machine = "IA64";
+ break;
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ machine = "x86";
+ break;
+ default:
+ machine = "unknown";
+ break;
+ }
+}
+
+}} // namespace qpid::sys