portability: use getifaddrs()

instead of exec'ing /usr/sbin/ifconfig|grep|sed|awk
This commit is contained in:
Sergei Golubchik 2014-09-29 19:50:56 +02:00
parent edd1de3d1c
commit 2156f62d2e
4 changed files with 29 additions and 48 deletions

View file

@ -76,6 +76,7 @@ SET(HAVE_FSYNC CACHE INTERNAL "")
SET(HAVE_FTIME 1 CACHE INTERNAL "") SET(HAVE_FTIME 1 CACHE INTERNAL "")
SET(HAVE_FTRUNCATE CACHE INTERNAL "") SET(HAVE_FTRUNCATE CACHE INTERNAL "")
SET(HAVE_GETADDRINFO 1 CACHE INTERNAL "") SET(HAVE_GETADDRINFO 1 CACHE INTERNAL "")
SET(HAVE_GETIFADDRS CACHE INTERNAL "")
SET(HAVE_GETCWD 1 CACHE INTERNAL "") SET(HAVE_GETCWD 1 CACHE INTERNAL "")
SET(HAVE_GETHOSTBYADDR_R CACHE INTERNAL "") SET(HAVE_GETHOSTBYADDR_R CACHE INTERNAL "")
SET(HAVE_GETHRTIME CACHE INTERNAL "") SET(HAVE_GETHRTIME CACHE INTERNAL "")

View file

@ -163,6 +163,7 @@
#cmakedefine HAVE_FSYNC 1 #cmakedefine HAVE_FSYNC 1
#cmakedefine HAVE_FTIME 1 #cmakedefine HAVE_FTIME 1
#cmakedefine HAVE_GETADDRINFO 1 #cmakedefine HAVE_GETADDRINFO 1
#cmakedefine HAVE_GETIFADDRS 1
#cmakedefine HAVE_GETCWD 1 #cmakedefine HAVE_GETCWD 1
#cmakedefine HAVE_GETHOSTBYADDR_R 1 #cmakedefine HAVE_GETHOSTBYADDR_R 1
#cmakedefine HAVE_GETHRTIME 1 #cmakedefine HAVE_GETHRTIME 1

View file

@ -371,6 +371,7 @@ CHECK_FUNCTION_EXISTS (getpassphrase HAVE_GETPASSPHRASE)
CHECK_FUNCTION_EXISTS (getpwnam HAVE_GETPWNAM) CHECK_FUNCTION_EXISTS (getpwnam HAVE_GETPWNAM)
CHECK_FUNCTION_EXISTS (getpwuid HAVE_GETPWUID) CHECK_FUNCTION_EXISTS (getpwuid HAVE_GETPWUID)
CHECK_FUNCTION_EXISTS (getrlimit HAVE_GETRLIMIT) CHECK_FUNCTION_EXISTS (getrlimit HAVE_GETRLIMIT)
CHECK_FUNCTION_EXISTS (getifaddrs HAVE_GETIFADDRS)
CHECK_FUNCTION_EXISTS (getrusage HAVE_GETRUSAGE) CHECK_FUNCTION_EXISTS (getrusage HAVE_GETRUSAGE)
CHECK_FUNCTION_EXISTS (getwd HAVE_GETWD) CHECK_FUNCTION_EXISTS (getwd HAVE_GETWD)
CHECK_FUNCTION_EXISTS (gmtime_r HAVE_GMTIME_R) CHECK_FUNCTION_EXISTS (gmtime_r HAVE_GMTIME_R)

View file

@ -34,6 +34,10 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> // getaddrinfo() #include <netdb.h> // getaddrinfo()
#ifdef HAVE_GETIFADDRS
#include <ifaddrs.h>
#endif
extern char** environ; // environment variables extern char** environ; // environment variables
static wsp::string wsrep_PATH; static wsp::string wsrep_PATH;
@ -371,7 +375,7 @@ size_t wsrep_guess_ip (char* buf, size_t buf_len)
{ {
size_t ip_len = 0; size_t ip_len = 0;
if (my_bind_addr_str && strlen(my_bind_addr_str)) if (my_bind_addr_str && my_bind_addr_str[0] != '\0')
{ {
unsigned int const ip_type= wsrep_check_ip(my_bind_addr_str); unsigned int const ip_type= wsrep_check_ip(my_bind_addr_str);
@ -405,55 +409,29 @@ size_t wsrep_guess_ip (char* buf, size_t buf_len)
return ip_len; return ip_len;
} }
// try to find the address of the first one #if HAVE_GETIFADDRS
#if (TARGET_OS_LINUX == 1) struct ifaddrs *ifaddr, *ifa;
const char cmd[] = "/sbin/ifconfig | " if (getifaddrs(&ifaddr) == 0)
// "grep -m1 -1 -E '^[a-z]?eth[0-9]' | tail -n 1 | " {
"grep -E '^[[:space:]]+inet addr:' | grep -m1 -v 'inet addr:127' | " for (ifa= ifaddr; ifa != NULL; ifa = ifa->ifa_next)
"sed 's/:/ /' | awk '{ print $3 }'"; {
#elif defined(__sun__) if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) // TODO AF_INET6
const char cmd[] = "/sbin/ifconfig -a | " continue;
"/usr/gnu/bin/grep -m1 -1 -E 'net[0-9]:' | tail -n 1 | awk '{ print $2 }'";
#elif defined(__APPLE__) || defined(__FreeBSD__) if (vio_getnameinfo(ifa->ifa_addr, buf, buf_len, NULL, 0, NI_NUMERICHOST))
const char cmd[] = "/sbin/route -nv get 8.8.8.8 | tail -n1 | awk '{print $(NF)}'"; continue;
#else
char *cmd; if (strcmp(buf, "127.0.0.1") == 0) // lame
#error "OS not supported" continue;
freeifaddrs(ifaddr);
return strlen(buf);
}
freeifaddrs(ifaddr);
}
#endif #endif
wsp::process proc (cmd, "r");
if (NULL != proc.pipe()) { return 0;
char* ret;
ret = fgets (buf, buf_len, proc.pipe());
if (proc.wait()) return 0;
if (NULL == ret) {
WSREP_ERROR("Failed to read output of: '%s'", cmd);
return 0;
}
}
else {
WSREP_ERROR("Failed to execute: '%s'", cmd);
return 0;
}
// clear possible \n at the end of ip string left by fgets()
ip_len = strlen (buf);
if (ip_len > 0 && '\n' == buf[ip_len - 1]) {
ip_len--;
buf[ip_len] = '\0';
}
if (INADDR_NONE == inet_addr(buf)) {
if (strlen(buf) != 0) {
WSREP_WARN("Shell command returned invalid address: '%s'", buf);
}
return 0;
}
return ip_len;
} }
size_t wsrep_guess_address(char* buf, size_t buf_len) size_t wsrep_guess_address(char* buf, size_t buf_len)