File: misc.c

package info (click to toggle)
hwloc-contrib 2.4.1%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: bullseye
  • size: 21,976 kB
  • sloc: ansic: 58,129; xml: 12,064; sh: 6,822; makefile: 2,200; javascript: 1,623; perl: 380; cpp: 93; php: 8; sed: 4
file content (153 lines) | stat: -rw-r--r-- 4,121 bytes parent folder | download | duplicates (20)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Copyright © 2009 CNRS
 * Copyright © 2009-2020 Inria.  All rights reserved.
 * Copyright © 2009-2010 Université Bordeaux
 * Copyright © 2009-2018 Cisco Systems, Inc.  All rights reserved.
 * See COPYING in top-level directory.
 */

#include "private/autogen/config.h"
#include "private/private.h"
#include "private/misc.h"

#include <stdarg.h>
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>

#ifdef HAVE_PROGRAM_INVOCATION_NAME
#include <errno.h>
extern char *program_invocation_name;
#endif
#ifdef HAVE___PROGNAME
extern char *__progname;
#endif

#ifndef HWLOC_HAVE_CORRECT_SNPRINTF
int hwloc_snprintf(char *str, size_t size, const char *format, ...)
{
  int ret;
  va_list ap;
  static char bin;
  size_t fakesize;
  char *fakestr;

  /* Some systems crash on str == NULL */
  if (!size) {
    str = &bin;
    size = 1;
  }

  va_start(ap, format);
  ret = vsnprintf(str, size, format, ap);
  va_end(ap);

  if (ret >= 0 && (size_t) ret != size-1)
    return ret;

  /* vsnprintf returned size-1 or -1. That could be a system which reports the
   * written data and not the actually required room. Try increasing buffer
   * size to get the latter. */

  fakesize = size;
  fakestr = NULL;
  do {
    fakesize *= 2;
    free(fakestr);
    fakestr = malloc(fakesize);
    if (NULL == fakestr)
      return -1;
    va_start(ap, format);
    errno = 0;
    ret = vsnprintf(fakestr, fakesize, format, ap);
    va_end(ap);
  } while ((size_t) ret == fakesize-1 || (ret < 0 && (!errno || errno == ERANGE)));

  if (ret >= 0 && size) {
    if (size > (size_t) ret+1)
      size = ret+1;
    memcpy(str, fakestr, size-1);
    str[size-1] = 0;
  }
  free(fakestr);

  return ret;
}
#endif

void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused,
			  void *cached_uname __hwloc_attribute_unused)
{
#ifdef HAVE_UNAME
  struct utsname _utsname, *utsname;

  if (hwloc_obj_get_info_by_name(topology->levels[0][0], "OSName"))
    /* don't annotate twice */
    return;

  if (cached_uname)
    utsname = (struct utsname *) cached_uname;
  else {
    utsname = &_utsname;
    if (uname(utsname) < 0)
      return;
  }

  if (*utsname->sysname)
    hwloc_obj_add_info(topology->levels[0][0], "OSName", utsname->sysname);
  if (*utsname->release)
    hwloc_obj_add_info(topology->levels[0][0], "OSRelease", utsname->release);
  if (*utsname->version)
    hwloc_obj_add_info(topology->levels[0][0], "OSVersion", utsname->version);
  if (*utsname->nodename)
    hwloc_obj_add_info(topology->levels[0][0], "HostName", utsname->nodename);
  if (*utsname->machine)
    hwloc_obj_add_info(topology->levels[0][0], "Architecture", utsname->machine);
#endif /* HAVE_UNAME */
}

char *
hwloc_progname(struct hwloc_topology *topology __hwloc_attribute_unused)
{
#if (defined HAVE_DECL_GETMODULEFILENAME) && HAVE_DECL_GETMODULEFILENAME
  char name[256], *local_basename;
  unsigned res = GetModuleFileName(NULL, name, sizeof(name));
  if (res == sizeof(name) || !res)
    return NULL;
  local_basename = strrchr(name, '\\');
  if (!local_basename)
    local_basename = name;
  else
    local_basename++;
  return strdup(local_basename);
#else /* !HAVE_GETMODULEFILENAME */
  const char *name, *local_basename;
#if HAVE_DECL_GETPROGNAME
  name = getprogname(); /* FreeBSD, NetBSD, some Solaris */
#elif HAVE_DECL_GETEXECNAME
  name = getexecname(); /* Solaris */
#elif defined HAVE_PROGRAM_INVOCATION_NAME
  name = program_invocation_name; /* Glibc. BGQ CNK. */
  /* could use program_invocation_short_name directly, but we have the code to remove the path below anyway */
#elif defined HAVE___PROGNAME
  name = __progname; /* fallback for most unix, used for OpenBSD */
#else
  /* TODO: _NSGetExecutablePath(path, &size) on Darwin */
  /* TODO: AIX, HPUX */
  name = NULL;
#endif
  if (!name)
    return NULL;
  local_basename = strrchr(name, '/');
  if (!local_basename)
    local_basename = name;
  else
    local_basename++;
  return strdup(local_basename);
#endif /* !HAVE_GETMODULEFILENAME */
}