| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- // Environment_UNIX.cpp
- //
- // $Id: //poco/1.4/Foundation/src/Environment_UNIX.cpp#2 $
- //
- // Library: Foundation
- // Package: Core
- // Module: Environment
- //
- // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
- // and Contributors.
- //
- // SPDX-License-Identifier: BSL-1.0
- //
- #include "Poco/Environment_UNIX.h"
- #include "Poco/Exception.h"
- #include "Poco/Buffer.h"
- #include <cstring>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/utsname.h>
- #include <sys/param.h>
- #if defined(POCO_OS_FAMILY_BSD)
- #include <sys/sysctl.h>
- #elif POCO_OS == POCO_OS_HPUX
- #include <pthread.h>
- #endif
- namespace Poco {
- EnvironmentImpl::StringMap EnvironmentImpl::_map;
- FastMutex EnvironmentImpl::_mutex;
- std::string EnvironmentImpl::getImpl(const std::string& name)
- {
- FastMutex::ScopedLock lock(_mutex);
-
- const char* val = getenv(name.c_str());
- if (val)
- return std::string(val);
- else
- throw NotFoundException(name);
- }
- bool EnvironmentImpl::hasImpl(const std::string& name)
- {
- FastMutex::ScopedLock lock(_mutex);
- return getenv(name.c_str()) != 0;
- }
- void EnvironmentImpl::setImpl(const std::string& name, const std::string& value)
- {
- FastMutex::ScopedLock lock(_mutex);
-
- std::string var = name;
- var.append("=");
- var.append(value);
- _map[name] = var;
- if (putenv((char*) _map[name].c_str()))
- {
- std::string msg = "cannot set environment variable: ";
- msg.append(name);
- throw SystemException(msg);
- }
- }
- std::string EnvironmentImpl::osNameImpl()
- {
- struct utsname uts;
- uname(&uts);
- return uts.sysname;
- }
- std::string EnvironmentImpl::osDisplayNameImpl()
- {
- return osNameImpl();
- }
- std::string EnvironmentImpl::osVersionImpl()
- {
- struct utsname uts;
- uname(&uts);
- return uts.release;
- }
- std::string EnvironmentImpl::osArchitectureImpl()
- {
- struct utsname uts;
- uname(&uts);
- return uts.machine;
- }
- std::string EnvironmentImpl::nodeNameImpl()
- {
- struct utsname uts;
- uname(&uts);
- return uts.nodename;
- }
- unsigned EnvironmentImpl::processorCountImpl()
- {
- #if defined(_SC_NPROCESSORS_ONLN)
- int count = sysconf(_SC_NPROCESSORS_ONLN);
- if (count <= 0) count = 1;
- return static_cast<int>(count);
- #elif defined(POCO_OS_FAMILY_BSD)
- unsigned count;
- std::size_t size = sizeof(count);
- if (sysctlbyname("hw.ncpu", &count, &size, 0, 0))
- return 1;
- else
- return count;
- #elif POCO_OS == POCO_OS_HPUX
- return pthread_num_processors_np();
- #else
- return 1;
- #endif
- }
- } // namespace Poco
- //
- // nodeIdImpl
- //
- #if defined(POCO_OS_FAMILY_BSD) || POCO_OS == POCO_OS_QNX
- //
- // BSD variants
- //
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <ifaddrs.h>
- #include <net/if_dl.h>
- namespace Poco {
- void EnvironmentImpl::nodeIdImpl(NodeId& id)
- {
- std::memset(&id, 0, sizeof(id));
- struct ifaddrs* ifaphead;
- int rc = getifaddrs(&ifaphead);
- if (rc) return;
- for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next)
- {
- if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_LINK)
- {
- struct sockaddr_dl* sdl = reinterpret_cast<struct sockaddr_dl*>(ifap->ifa_addr);
- caddr_t ap = LLADDR(sdl);
- int alen = sdl->sdl_alen;
- if (ap && alen > 0)
- {
- std::memcpy(&id, ap, sizeof(id));
- break;
- }
- }
- }
- freeifaddrs(ifaphead);
- }
- } // namespace Poco
- #elif defined(__CYGWIN__) || POCO_OS == POCO_OS_LINUX
- //
- // Linux, Cygwin
- //
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <net/if.h>
- #ifndef __CYGWIN__
- #include <net/if_arp.h>
- #else // workaround for Cygwin, which does not have if_arp.h
- #define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
- #endif
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <cstdio>
- namespace Poco {
- void EnvironmentImpl::nodeIdImpl(NodeId& id)
- {
- std::memset(&id, 0, sizeof(id));
- // ideally, the following code should be rewritten
- // to use netlink
- // first try to obtain the MAC address of eth0 using /sys/class/net
- int fd = open("/sys/class/net/eth0/address", O_RDONLY);
- if (fd >= 0)
- {
- char buffer[18];
- int n = read(fd, buffer, 17);
- close(fd);
- if (n == 17)
- {
- buffer[n] = 0;
- if (std::sscanf(buffer, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &id[0], &id[1], &id[2], &id[3], &id[4], &id[5]) == 6)
- return;
- }
- }
- // if that did not work, search active interfaces
- int sock = socket(PF_INET, SOCK_DGRAM, 0);
- if (sock == -1) return;
- // the following code is loosely based
- // on W. Richard Stevens, UNIX Network Programming, pp 434ff.
- int lastlen = 0;
- int len = 100*sizeof(struct ifreq);
- struct ifconf ifc;
- char* buf = 0;
- for (;;)
- {
- buf = new char[len];
- ifc.ifc_len = len;
- ifc.ifc_buf = buf;
- if (::ioctl(sock, SIOCGIFCONF, &ifc) < 0)
- {
- if (errno != EINVAL || lastlen != 0)
- {
- close(sock);
- delete [] buf;
- return;
- }
- }
- else
- {
- if (ifc.ifc_len == lastlen)
- break;
- lastlen = ifc.ifc_len;
- }
- len += 10*sizeof(struct ifreq);
- delete [] buf;
- }
- for (const char* ptr = buf; ptr < buf + ifc.ifc_len;)
- {
- const struct ifreq* ifr = reinterpret_cast<const struct ifreq*>(ptr);
- int rc = ioctl(sock, SIOCGIFHWADDR, ifr);
- if (rc != -1)
- {
- const struct sockaddr* sa = reinterpret_cast<const struct sockaddr*>(&ifr->ifr_hwaddr);
- if (sa->sa_family == ARPHRD_ETHER)
- {
- std::memcpy(&id, sa->sa_data, sizeof(id));
- break;
- }
- }
- ptr += sizeof(struct ifreq);
- }
- close(sock);
- delete [] buf;
- }
- } // namespace Poco
- #elif defined(POCO_OS_FAMILY_UNIX)
- //
- // General Unix
- //
- #include <sys/ioctl.h>
- #if defined(sun) || defined(__sun)
- #include <sys/sockio.h>
- #endif
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <net/if.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <net/if.h>
- #include <net/if_arp.h>
- #include <unistd.h>
- namespace Poco {
- void EnvironmentImpl::nodeIdImpl(NodeId& id)
- {
- std::memset(&id, 0, sizeof(id));
- char name[MAXHOSTNAMELEN];
- if (gethostname(name, sizeof(name)))
- return;
- struct hostent* pHost = gethostbyname(name);
- if (!pHost) return;
- int s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (s == -1) return;
- struct arpreq ar;
- std::memset(&ar, 0, sizeof(ar));
- struct sockaddr_in* pAddr = reinterpret_cast<struct sockaddr_in*>(&ar.arp_pa);
- pAddr->sin_family = AF_INET;
- std::memcpy(&pAddr->sin_addr, *pHost->h_addr_list, sizeof(struct in_addr));
- int rc = ioctl(s, SIOCGARP, &ar);
- close(s);
- if (rc < 0) return;
- std::memcpy(&id, ar.arp_ha.sa_data, sizeof(id));
- }
- } // namespace Poco
- #endif
|