diff options
author | Stephen D. Huston <shuston@apache.org> | 2008-10-09 15:20:49 +0000 |
---|---|---|
committer | Stephen D. Huston <shuston@apache.org> | 2008-10-09 15:20:49 +0000 |
commit | 0b195851725cd2b0982d26a108e7239eca6b2052 (patch) | |
tree | 0eeaa66dc3daa0147c92995cda6b0f014ac8c512 /cpp/src | |
parent | bfa255f4fd7a67f1433b424913515633d7e58c2f (diff) | |
download | qpid-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.am | 3 | ||||
-rwxr-xr-x | cpp/src/qpid/Address.h | 53 | ||||
-rw-r--r-- | cpp/src/qpid/Url.cpp | 30 | ||||
-rw-r--r-- | cpp/src/qpid/Url.h | 23 | ||||
-rw-r--r-- | cpp/src/qpid/broker/System.cpp | 22 | ||||
-rw-r--r-- | cpp/src/qpid/sys/SystemInfo.cpp | 35 | ||||
-rw-r--r-- | cpp/src/qpid/sys/SystemInfo.h | 38 | ||||
-rwxr-xr-x | cpp/src/qpid/sys/posix/SystemInfo.cpp | 95 | ||||
-rwxr-xr-x | cpp/src/qpid/sys/windows/SystemInfo.cpp | 160 |
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 |