From 84b8fff7b18eaa8094019d8abe3f99a0782a5cae Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Sun, 24 Sep 2006 18:23:04 +0000 Subject: [PATCH] start port of OperatingSystem.java to sigar_sys_info C api --- include/sigar.h | 16 ++++ include/sigar_private.h | 4 + src/os/aix/aix_sigar.c | 8 ++ src/os/darwin/darwin_sigar.c | 24 +++++ src/os/hpux/hpux_sigar.c | 9 ++ src/os/linux/linux_sigar.c | 168 +++++++++++++++++++++++++++++++++ src/os/netware/netware_sigar.c | 8 ++ src/os/osf1/osf1_sigar.c | 6 ++ src/os/solaris/solaris_sigar.c | 9 ++ src/os/stub/stub_sigar.c | 6 ++ src/os/win32/win32_sigar.c | 6 ++ src/sigar.c | 34 +++++++ 12 files changed, 298 insertions(+) diff --git a/include/sigar.h b/include/sigar.h index 4e3b37f9..d5ec47c6 100644 --- a/include/sigar.h +++ b/include/sigar.h @@ -671,6 +671,22 @@ typedef struct { SIGAR_DECLARE(sigar_version_t *) sigar_version_get(void); +#define SIGAR_SYS_INFO_LEN SIGAR_MAXHOSTNAMELEN /* more than enough */ + +typedef struct { + char name[SIGAR_SYS_INFO_LEN]; /* canonicalized sysname */ + char version[SIGAR_SYS_INFO_LEN]; /* utsname.release */ + char arch[SIGAR_SYS_INFO_LEN]; + char description[SIGAR_SYS_INFO_LEN]; + char patch_level[SIGAR_SYS_INFO_LEN]; + char vendor[SIGAR_SYS_INFO_LEN]; + char vendor_version[SIGAR_SYS_INFO_LEN]; + char vendor_name[SIGAR_SYS_INFO_LEN]; /* utsname.sysname */ + char vendor_code_name[SIGAR_SYS_INFO_LEN]; +} sigar_sys_info_t; + +SIGAR_DECLARE(int) sigar_sys_info_get(sigar_t *sigar, sigar_sys_info_t *sysinfo); + #define SIGAR_FQDN_LEN 512 SIGAR_DECLARE(int) sigar_fqdn_get(sigar_t *sigar, char *name, int namelen); diff --git a/include/sigar_private.h b/include/sigar_private.h index cab4e68d..54f71a31 100644 --- a/include/sigar_private.h +++ b/include/sigar_private.h @@ -133,6 +133,10 @@ int sigar_os_close(sigar_t *sigar); char *sigar_os_error_string(sigar_t *sigar, int err); +int sigar_sys_info_get_uname(sigar_sys_info_t *sysinfo); + +int sigar_os_sys_info_get(sigar_t *sigar, sigar_sys_info_t *sysinfo); + int sigar_proc_list_create(sigar_proc_list_t *proclist); int sigar_proc_list_grow(sigar_proc_list_t *proclist); diff --git a/src/os/aix/aix_sigar.c b/src/os/aix/aix_sigar.c index f7b21b0e..cd2f2b2a 100644 --- a/src/os/aix/aix_sigar.c +++ b/src/os/aix/aix_sigar.c @@ -2351,3 +2351,11 @@ int sigar_proc_port_get(sigar_t *sigar, int protocol, return ENOENT; } + +int sigar_os_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + SIGAR_SSTRCPY(sysinfo->vendor, "IBM"); + + return SIGAR_OK; +} diff --git a/src/os/darwin/darwin_sigar.c b/src/os/darwin/darwin_sigar.c index 5cbc0c28..050bce03 100644 --- a/src/os/darwin/darwin_sigar.c +++ b/src/os/darwin/darwin_sigar.c @@ -2181,3 +2181,27 @@ int sigar_proc_port_get(sigar_t *sigar, int protocol, } #endif + +int sigar_os_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ +#ifdef DARWIN + char *codename = NULL; + SIGAR_SSTRCPY(sysinfo->name, "MacOSX"); + SIGAR_SSTRCPY(sysinfo->vendor, "Apple"); + + if (strnEQ(sysinfo->version, "10.4", 4)) { + codename = "Tiger"; + } + else if (strnEQ(sysinfo->version, "10.3", 4)) { + codename = "Panther"; + } + + if (codename) { + SIGAR_SSTRCPY(sysinfo->vendor_code_name, codename); + } +#else +#endif + + return SIGAR_OK; +} diff --git a/src/os/hpux/hpux_sigar.c b/src/os/hpux/hpux_sigar.c index 1917df2e..2890a6dd 100644 --- a/src/os/hpux/hpux_sigar.c +++ b/src/os/hpux/hpux_sigar.c @@ -1041,3 +1041,12 @@ int sigar_proc_port_get(sigar_t *sigar, int protocol, { return SIGAR_ENOTIMPL; } + +int sigar_os_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + SIGAR_SSTRCPY(sysinfo->name, "HPUX"); + SIGAR_SSTRCPY(sysinfo->vendor, "Hewlett-Packard"); + /* XXX fixup version */ + return SIGAR_OK; +} diff --git a/src/os/linux/linux_sigar.c b/src/os/linux/linux_sigar.c index 70656884..44079577 100644 --- a/src/os/linux/linux_sigar.c +++ b/src/os/linux/linux_sigar.c @@ -2108,3 +2108,171 @@ int sigar_proc_port_get(sigar_t *sigar, int protocol, return SIGAR_OK; } + +static void generic_vendor_parse(char *line, sigar_sys_info_t *info) +{ + char *ptr; + int len = 0; + + while (*line) { + SIGAR_SKIP_SPACE(line); + if (!isdigit(*line)) { + ++line; + continue; + } + + ptr = line; + while ((isdigit(*ptr) || (*ptr == '.'))) { + ++ptr; + ++len; + } + + if (len) { + /* sanity check */ + if (len > sizeof(info->vendor_version)) { + continue; + } + memcpy(info->vendor_version, line, len);/*XXX*/ + info->vendor_version[len] = '\0'; + return; + } + } +} + +static void redhat_vendor_parse(char *line, sigar_sys_info_t *info) +{ + char *start, *end; + + generic_vendor_parse(line, info); /* super.parse */ + + if ((start = strchr(line, '('))) { + ++start; + if ((end = strchr(start, ')'))) { + int len = end-start; + memcpy(info->vendor_code_name, start, len);/*XXX*/ + info->vendor_code_name[len] = '\0'; + } + } + +#define RHEL_PREFIX "Red Hat Enterprise Linux " +#define CENTOS_VENDOR "CentOS" + if (strnEQ(line, RHEL_PREFIX, sizeof(RHEL_PREFIX)-1)) { + /*XXX*/ + } + else if (strnEQ(line, CENTOS_VENDOR, sizeof(CENTOS_VENDOR)-1)) { + SIGAR_SSTRCPY(info->vendor, CENTOS_VENDOR); + } +} + +static void lsb_vendor_parse(char *data, sigar_sys_info_t *info) +{ + char *ptr = data; + int len = strlen(data); + char *end = data+len; + + while (ptr < end) { + char *val = strchr(ptr, '='); + int klen, vlen; + char key[256], *ix; + + if (!val) { + continue; + } + klen = val - ptr; + SIGAR_SSTRCPY(key, ptr); + key[klen] = '\0'; + ++val; + + if ((ix = strchr(val, '\n'))) { + *ix = '\0'; + } + vlen = strlen(val); + + if (strEQ(key, "DISTRIB_ID")) { + SIGAR_SSTRCPY(info->vendor, val); + } + else if (strEQ(key, "DISTRIB_RELEASE")) { + SIGAR_SSTRCPY(info->vendor_version, val); + } + else if (strEQ(key, "DISTRIB_CODENAME")) { + SIGAR_SSTRCPY(info->vendor_code_name, val); + } + + ptr += (klen + 1 + vlen + 1); + } +} + +typedef struct { + const char *name; + const char *file; + void (*parse)(char *, sigar_sys_info_t *); +} linux_vendor_info_t; + +static linux_vendor_info_t linux_vendors[] = { + { "Red Hat", "/etc/redhat-release", redhat_vendor_parse }, + { "Fedora", "/etc/fedora-release", NULL }, + { "SuSE", "/etc/SuSE-release", NULL }, + { "Debian", "/etc/debian_version", NULL }, + { "Gentoo", "/etc/gentoo-release", NULL }, + { "Slackware", "/etc/slackware-version", NULL }, + { "Mandrake", "/etc/mandrake-release", NULL }, + { "VMware", "/proc/vmware/version", NULL }, + { "lsb", "/etc/lsb-release", lsb_vendor_parse }, + { NULL } +}; + +static int get_linux_vendor_info(sigar_sys_info_t *info) +{ + int i, status = ENOENT; + /* env vars for testing */ + const char *release_file = getenv("SIGAR_OS_RELEASE_FILE"); + const char *vendor_name = getenv("SIGAR_OS_VENDOR_NAME"); + char buffer[8192], *data; + linux_vendor_info_t *vendor = NULL; + + for (i=0; linux_vendors[i].name; i++) { + struct stat sb; + vendor = &linux_vendors[i]; + + if (release_file && vendor_name) { + if (!strEQ(vendor->name, vendor_name)) { + continue; + } + } + else { + if (stat(vendor->file, &sb) < 0) { + continue; + } + release_file = vendor->file; + } + + status = + sigar_file2str(release_file, buffer, sizeof(buffer)-1); + + break; + } + + if (status != SIGAR_OK) { + return status; + } + + data = buffer; + + if (vendor->parse) { + vendor->parse(data, info); + } + else { + generic_vendor_parse(data, info); + } + + return SIGAR_OK; +} + +int sigar_os_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + + get_linux_vendor_info(sysinfo); + + return SIGAR_OK; +} diff --git a/src/os/netware/netware_sigar.c b/src/os/netware/netware_sigar.c index 55b93b7b..d487558e 100644 --- a/src/os/netware/netware_sigar.c +++ b/src/os/netware/netware_sigar.c @@ -434,3 +434,11 @@ int sigar_nfs_ping(char *host) { return SIGAR_ENOTIMPL; } + +int sigar_os_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + SIGAR_SSTRCPY(sysinfo->vendor, "Novell"); + + return SIGAR_OK; +} diff --git a/src/os/osf1/osf1_sigar.c b/src/os/osf1/osf1_sigar.c index 1beea745..d46ecdf9 100644 --- a/src/os/osf1/osf1_sigar.c +++ b/src/os/osf1/osf1_sigar.c @@ -553,3 +553,9 @@ int sigar_proc_port_get(sigar_t *sigar, int protocol, { return SIGAR_ENOTIMPL; } + +int sigar_os_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + return SIGAR_OK; +} diff --git a/src/os/solaris/solaris_sigar.c b/src/os/solaris/solaris_sigar.c index bf1f610b..2dc09269 100644 --- a/src/os/solaris/solaris_sigar.c +++ b/src/os/solaris/solaris_sigar.c @@ -2293,3 +2293,12 @@ int sigar_proc_port_get(sigar_t *sigar, int protocol, { return SIGAR_ENOTIMPL; } + +int sigar_os_ys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + SIGAR_SSTRCPY(sysinfo->name, "Solaris"); + SIGAR_SSTRCPY(sysinfo->vendor, "Sun Microsystems"); + + return SIGAR_OK; +} diff --git a/src/os/stub/stub_sigar.c b/src/os/stub/stub_sigar.c index 993ed315..f66c9426 100644 --- a/src/os/stub/stub_sigar.c +++ b/src/os/stub/stub_sigar.c @@ -265,3 +265,9 @@ int sigar_proc_port_get(sigar_t *sigar, int protocol, { return SIGAR_ENOTIMPL; } + +int sigar_os_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + return SIGAR_OK; +} diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index 610c374d..1167e282 100644 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -2726,3 +2726,9 @@ int sigar_who_list_get_win32(sigar_t *sigar, return SIGAR_OK; } + +int sigar_os_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + return SIGAR_OK; +} diff --git a/src/sigar.c b/src/sigar.c index 95ca949e..5ecd503b 100644 --- a/src/sigar.c +++ b/src/sigar.c @@ -1211,6 +1211,40 @@ int sigar_net_info_get(sigar_t *sigar, return SIGAR_OK; } +#ifndef WIN32 + +#include + +int sigar_sys_info_get_uname(sigar_sys_info_t *sysinfo) +{ + struct utsname name; + + uname(&name); + + SIGAR_SSTRCPY(sysinfo->version, name.release); + SIGAR_SSTRCPY(sysinfo->vendor_name, name.sysname); + SIGAR_SSTRCPY(sysinfo->name, name.sysname); + SIGAR_SSTRCPY(sysinfo->arch, name.machine); + SIGAR_SSTRCPY(sysinfo->patch_level, "unknown"); + + return SIGAR_OK; +} +#endif + +SIGAR_DECLARE(int) sigar_sys_info_get(sigar_t *sigar, + sigar_sys_info_t *sysinfo) +{ + SIGAR_ZERO(sysinfo); + +#ifndef WIN32 + sigar_sys_info_get_uname(sysinfo); +#endif + + sigar_os_sys_info_get(sigar, sysinfo); + + return SIGAR_OK; +} + #include #define OffsetOf(structure, field) \