tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

prsystem.c (7697B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "primpl.h"
      7 #include "prsystem.h"
      8 #include "prprf.h"
      9 #include "prlong.h"
     10 
     11 /* BSD-derived systems use sysctl() to get the number of processors */
     12 #if defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) || \
     13    defined(DRAGONFLY) || defined(DARWIN)
     14 #  define _PR_HAVE_SYSCTL
     15 #  include <sys/param.h>
     16 #  include <sys/sysctl.h>
     17 #endif
     18 
     19 #if defined(DARWIN)
     20 #  include <mach/mach_init.h>
     21 #  include <mach/mach_host.h>
     22 #  include <mach/mach_port.h>
     23 #endif
     24 
     25 
     26 #if defined(XP_UNIX)
     27 #  include <unistd.h>
     28 #  include <sys/utsname.h>
     29 #endif
     30 
     31 #if defined(LINUX)
     32 #  include <string.h>
     33 #  include <ctype.h>
     34 #  define MAX_LINE 512
     35 #endif
     36 
     37 #if defined(AIX)
     38 #  include <cf.h>
     39 #  include <sys/cfgodm.h>
     40 #endif
     41 
     42 PR_IMPLEMENT(char) PR_GetDirectorySeparator(void) {
     43  return PR_DIRECTORY_SEPARATOR;
     44 } /* PR_GetDirectorySeparator */
     45 
     46 /*
     47 ** OBSOLETE -- the function name is misspelled.
     48 */
     49 PR_IMPLEMENT(char) PR_GetDirectorySepartor(void) {
     50 #if defined(DEBUG)
     51  static PRBool warn = PR_TRUE;
     52  if (warn) {
     53    warn =
     54        _PR_Obsolete("PR_GetDirectorySepartor()", "PR_GetDirectorySeparator()");
     55  }
     56 #endif
     57  return PR_GetDirectorySeparator();
     58 } /* PR_GetDirectorySepartor */
     59 
     60 PR_IMPLEMENT(char) PR_GetPathSeparator(void) {
     61  return PR_PATH_SEPARATOR;
     62 } /* PR_GetPathSeparator */
     63 
     64 PR_IMPLEMENT(PRStatus)
     65 PR_GetSystemInfo(PRSysInfo cmd, char* buf, PRUint32 buflen) {
     66  PRUintn len = 0;
     67 
     68  if (!_pr_initialized) {
     69    _PR_ImplicitInitialization();
     70  }
     71 
     72  switch (cmd) {
     73    case PR_SI_HOSTNAME:
     74    case PR_SI_HOSTNAME_UNTRUNCATED:
     75      if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen)) {
     76        return PR_FAILURE;
     77      }
     78 
     79      if (cmd == PR_SI_HOSTNAME_UNTRUNCATED) {
     80        break;
     81      }
     82      /*
     83       * On some platforms a system does not have a hostname and
     84       * its IP address is returned instead.   The following code
     85       * should be skipped on those platforms.
     86       */
     87 #ifndef _PR_GET_HOST_ADDR_AS_NAME
     88      /* Return the unqualified hostname */
     89      while (buf[len] && (len < buflen)) {
     90        if (buf[len] == '.') {
     91          buf[len] = '\0';
     92          break;
     93        }
     94        len += 1;
     95      }
     96 #endif
     97      break;
     98 
     99    case PR_SI_SYSNAME:
    100      /* Return the operating system name */
    101 #if defined(XP_UNIX) || defined(WIN32)
    102      if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) {
    103        return PR_FAILURE;
    104      }
    105 #else
    106      (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME);
    107 #endif
    108      break;
    109 
    110    case PR_SI_RELEASE:
    111      /* Return the version of the operating system */
    112 #if defined(XP_UNIX) || defined(WIN32)
    113      if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) {
    114        return PR_FAILURE;
    115      }
    116 #endif
    117      break;
    118 
    119    case PR_SI_RELEASE_BUILD:
    120      /* Return the version of the operating system */
    121 #if defined(XP_UNIX) || defined(WIN32)
    122      if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) {
    123        return PR_FAILURE;
    124      }
    125 #else
    126      if (buflen) {
    127        *buf = 0;
    128      }
    129 #endif /* XP_UNIX || WIN32 */
    130      break;
    131 
    132    case PR_SI_ARCHITECTURE:
    133      /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/
    134      (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE);
    135      break;
    136    default:
    137      PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    138      return PR_FAILURE;
    139  }
    140  return PR_SUCCESS;
    141 }
    142 
    143 /*
    144 ** PR_GetNumberOfProcessors()
    145 **
    146 ** Implementation notes:
    147 **   Every platform does it a bit different.
    148 **     numCpus is the returned value.
    149 **   for each platform's "if defined" section
    150 **     declare your local variable
    151 **     do your thing, assign to numCpus
    152 **   order of the if defined()s may be important,
    153 **     especially for unix variants. Do platform
    154 **     specific implementations before XP_UNIX.
    155 **
    156 */
    157 PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors(void) {
    158  PRInt32 numCpus;
    159 #if defined(WIN32)
    160  SYSTEM_INFO info;
    161 
    162  GetSystemInfo(&info);
    163  numCpus = info.dwNumberOfProcessors;
    164 #elif defined(_PR_HAVE_SYSCTL)
    165  int mib[2];
    166  int rc;
    167  size_t len = sizeof(numCpus);
    168 
    169  mib[0] = CTL_HW;
    170 #  ifdef HW_NCPUONLINE
    171  mib[1] = HW_NCPUONLINE;
    172 #  else
    173  mib[1] = HW_NCPU;
    174 #  endif
    175  rc = sysctl(mib, 2, &numCpus, &len, NULL, 0);
    176  if (-1 == rc) {
    177    numCpus = -1; /* set to -1 for return value on error */
    178    _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
    179  }
    180 #elif defined(RISCOS)
    181  numCpus = 1;
    182 #elif defined(LINUX)
    183  /* for the benefit of devices with advanced power-saving, that
    184     actually hotplug their cpus in heavy load, try to figure out
    185     the real number of CPUs */
    186  char buf[MAX_LINE];
    187  FILE* fin;
    188  const char* cpu_present = "/sys/devices/system/cpu/present";
    189  size_t strsize;
    190  numCpus = 0;
    191  fin = fopen(cpu_present, "r");
    192  if (fin != NULL) {
    193    if (fgets(buf, MAX_LINE, fin) != NULL) {
    194      /* check that the format is what we expect */
    195      if (buf[0] == '0') {
    196        strsize = strlen(buf);
    197        if (strsize == 1) {
    198          /* single core */
    199          numCpus = 1;
    200        } else if (strsize >= 3 && strsize <= 5) {
    201          /* should be of the form 0-999 */
    202          /* parse the part after the 0-, note count is 0-based */
    203          if (buf[1] == '-' && isdigit(buf[2])) {
    204            numCpus = 1 + atoi(buf + 2);
    205          }
    206        }
    207      }
    208    }
    209    fclose(fin);
    210  }
    211  /* if that fails, fall back to more standard methods */
    212  if (!numCpus) {
    213    numCpus = sysconf(_SC_NPROCESSORS_CONF);
    214  }
    215 #elif defined(XP_UNIX)
    216  numCpus = sysconf(_SC_NPROCESSORS_CONF);
    217 #else
    218 #  error "An implementation is required"
    219 #endif
    220  return (numCpus);
    221 } /* end PR_GetNumberOfProcessors() */
    222 
    223 /*
    224 ** PR_GetPhysicalMemorySize()
    225 **
    226 ** Implementation notes:
    227 **   Every platform does it a bit different.
    228 **     bytes is the returned value.
    229 **   for each platform's "if defined" section
    230 **     declare your local variable
    231 **     do your thing, assign to bytes.
    232 **
    233 */
    234 PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void) {
    235  PRUint64 bytes = 0;
    236 
    237 #if defined(LINUX) || defined(SOLARIS)
    238 
    239  long pageSize = sysconf(_SC_PAGESIZE);
    240  long pageCount = sysconf(_SC_PHYS_PAGES);
    241  if (pageSize >= 0 && pageCount >= 0) {
    242    bytes = (PRUint64)pageSize * pageCount;
    243  }
    244 
    245 #elif defined(NETBSD) || defined(OPENBSD) || defined(FREEBSD) || \
    246    defined(DRAGONFLY)
    247 
    248  int mib[2];
    249  int rc;
    250 #  ifdef HW_PHYSMEM64
    251  uint64_t memSize;
    252 #  else
    253  unsigned long memSize;
    254 #  endif
    255  size_t len = sizeof(memSize);
    256 
    257  mib[0] = CTL_HW;
    258 #  ifdef HW_PHYSMEM64
    259  mib[1] = HW_PHYSMEM64;
    260 #  else
    261  mib[1] = HW_PHYSMEM;
    262 #  endif
    263  rc = sysctl(mib, 2, &memSize, &len, NULL, 0);
    264  if (-1 != rc) {
    265    bytes = memSize;
    266  }
    267 
    268 #elif defined(DARWIN)
    269 
    270  mach_port_t mach_host = mach_host_self();
    271  struct host_basic_info hInfo;
    272  mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
    273 
    274  int result =
    275      host_info(mach_host, HOST_BASIC_INFO, (host_info_t)&hInfo, &count);
    276  mach_port_deallocate(mach_task_self(), mach_host);
    277  if (result == KERN_SUCCESS) {
    278    bytes = hInfo.max_mem;
    279  }
    280 
    281 #elif defined(WIN32)
    282 
    283  MEMORYSTATUSEX memStat;
    284  memStat.dwLength = sizeof(memStat);
    285  if (GlobalMemoryStatusEx(&memStat)) {
    286    bytes = memStat.ullTotalPhys;
    287  }
    288 
    289 #elif defined(AIX)
    290 
    291  if (odm_initialize() == 0) {
    292    int how_many;
    293    struct CuAt* obj = getattr("sys0", "realmem", 0, &how_many);
    294    if (obj != NULL) {
    295      bytes = (PRUint64)atoi(obj->value) * 1024;
    296      free(obj);
    297    }
    298    odm_terminate();
    299  }
    300 
    301 #else
    302 
    303  PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    304 
    305 #endif
    306 
    307  return bytes;
    308 } /* end PR_GetPhysicalMemorySize() */