Update hwloc to v1.11.12
[charm.git] / contrib / hwloc / src / misc.c
blob4e9d6055be2048b867d6101f62decdc698883345
1 /*
2 * Copyright © 2009 CNRS
3 * Copyright © 2009-2014 Inria. All rights reserved.
4 * Copyright © 2009-2010 Université Bordeaux
5 * Copyright © 2009-2018 Cisco Systems, Inc. All rights reserved.
6 * See COPYING in top-level directory.
7 */
9 #include <private/autogen/config.h>
10 #include <private/private.h>
11 #include <private/misc.h>
13 #include <stdarg.h>
14 #ifdef HAVE_SYS_UTSNAME_H
15 #include <sys/utsname.h>
16 #endif
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdio.h>
20 #include <errno.h>
21 #include <ctype.h>
23 #ifdef HAVE_PROGRAM_INVOCATION_NAME
24 #include <errno.h>
25 extern char *program_invocation_name;
26 #endif
27 #ifdef HAVE___PROGNAME
28 extern char *__progname;
29 #endif
31 int hwloc_snprintf(char *str, size_t size, const char *format, ...)
33 int ret;
34 va_list ap;
35 static char bin;
36 size_t fakesize;
37 char *fakestr;
39 /* Some systems crash on str == NULL */
40 if (!size) {
41 str = &bin;
42 size = 1;
45 va_start(ap, format);
46 ret = vsnprintf(str, size, format, ap);
47 va_end(ap);
49 if (ret >= 0 && (size_t) ret != size-1)
50 return ret;
52 /* vsnprintf returned size-1 or -1. That could be a system which reports the
53 * written data and not the actually required room. Try increasing buffer
54 * size to get the latter. */
56 fakesize = size;
57 fakestr = NULL;
58 do {
59 fakesize *= 2;
60 free(fakestr);
61 fakestr = malloc(fakesize);
62 if (NULL == fakestr)
63 return -1;
64 va_start(ap, format);
65 errno = 0;
66 ret = vsnprintf(fakestr, fakesize, format, ap);
67 va_end(ap);
68 } while ((size_t) ret == fakesize-1 || (ret < 0 && (!errno || errno == ERANGE)));
70 if (ret >= 0 && size) {
71 if (size > (size_t) ret+1)
72 size = ret+1;
73 memcpy(str, fakestr, size-1);
74 str[size-1] = 0;
76 free(fakestr);
78 return ret;
81 int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n)
83 size_t i = 0;
84 while (*haystack && *haystack != ':') {
85 int ha = *haystack++;
86 int low_h = tolower(ha);
87 int ne = *needle++;
88 int low_n = tolower(ne);
89 if (low_h != low_n)
90 return 1;
91 i++;
93 return i < n;
96 void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused,
97 void *cached_uname __hwloc_attribute_unused)
99 #ifdef HAVE_UNAME
100 struct utsname _utsname, *utsname;
102 if (hwloc_obj_get_info_by_name(topology->levels[0][0], "OSName"))
103 /* don't annotate twice */
104 return;
106 if (cached_uname)
107 utsname = (struct utsname *) cached_uname;
108 else {
109 utsname = &_utsname;
110 if (uname(utsname) < 0)
111 return;
114 if (*utsname->sysname)
115 hwloc_obj_add_info(topology->levels[0][0], "OSName", utsname->sysname);
116 if (*utsname->release)
117 hwloc_obj_add_info(topology->levels[0][0], "OSRelease", utsname->release);
118 if (*utsname->version)
119 hwloc_obj_add_info(topology->levels[0][0], "OSVersion", utsname->version);
120 if (*utsname->nodename)
121 hwloc_obj_add_info(topology->levels[0][0], "HostName", utsname->nodename);
122 if (*utsname->machine)
123 hwloc_obj_add_info(topology->levels[0][0], "Architecture", utsname->machine);
124 #endif /* HAVE_UNAME */
127 char *
128 hwloc_progname(struct hwloc_topology *topology __hwloc_attribute_unused)
130 #if HAVE_DECL_GETMODULEFILENAME
131 char name[256], *local_basename;
132 unsigned res = GetModuleFileName(NULL, name, sizeof(name));
133 if (res == sizeof(name) || !res)
134 return NULL;
135 local_basename = strrchr(name, '\\');
136 if (!local_basename)
137 local_basename = name;
138 else
139 local_basename++;
140 return strdup(local_basename);
141 #else /* !HAVE_GETMODULEFILENAME */
142 const char *name, *local_basename;
143 #if HAVE_DECL_GETPROGNAME
144 name = getprogname(); /* FreeBSD, NetBSD, some Solaris */
145 #elif HAVE_DECL_GETEXECNAME
146 name = getexecname(); /* Solaris */
147 #elif defined HAVE_PROGRAM_INVOCATION_NAME
148 name = program_invocation_name; /* Glibc. BGQ CNK. */
149 /* could use program_invocation_short_name directly, but we have the code to remove the path below anyway */
150 #elif defined HAVE___PROGNAME
151 name = __progname; /* fallback for most unix, used for OpenBSD */
152 #else
153 /* TODO: _NSGetExecutablePath(path, &size) on Darwin */
154 /* TODO: AIX, HPUX, OSF */
155 name = NULL;
156 #endif
157 if (!name)
158 return NULL;
159 local_basename = strrchr(name, '/');
160 if (!local_basename)
161 local_basename = name;
162 else
163 local_basename++;
164 return strdup(local_basename);
165 #endif /* !HAVE_GETMODULEFILENAME */