summaryrefslogtreecommitdiffstats
path: root/gl/getloadavg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/getloadavg.c')
-rw-r--r--gl/getloadavg.c178
1 files changed, 49 insertions, 129 deletions
diff --git a/gl/getloadavg.c b/gl/getloadavg.c
index 6e228191..37e82808 100644
--- a/gl/getloadavg.c
+++ b/gl/getloadavg.c
@@ -1,6 +1,6 @@
1/* Get the system load averages. 1/* Get the system load averages.
2 2
3 Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2013 Free Software 3 Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2022 Free Software
4 Foundation, Inc. 4 Foundation, Inc.
5 5
6 NOTE: The canonical source of this file is maintained with gnulib. 6 NOTE: The canonical source of this file is maintained with gnulib.
@@ -8,7 +8,7 @@
8 8
9 This program is free software: you can redistribute it and/or modify 9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by 10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or 11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14 This program is distributed in the hope that it will be useful, 14 This program is distributed in the hope that it will be useful,
@@ -17,7 +17,7 @@
17 GNU General Public License for more details. 17 GNU General Public License for more details.
18 18
19 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 along with this program. If not, see <https://www.gnu.org/licenses/>. */
21 21
22/* Compile-time symbols that this file uses: 22/* Compile-time symbols that this file uses:
23 23
@@ -47,29 +47,25 @@
47 N_NAME_POINTER The nlist n_name element is a pointer, 47 N_NAME_POINTER The nlist n_name element is a pointer,
48 not an array. 48 not an array.
49 HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'. 49 HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'.
50 LINUX_LDAV_FILE [__linux__, __CYGWIN__]: File containing 50 LINUX_LDAV_FILE [__linux__, __ANDROID__, __CYGWIN__]: File
51 load averages. 51 containing load averages.
52 52
53 Specific system predefines this file uses, aside from setting 53 Specific system predefines this file uses, aside from setting
54 default values if not emacs: 54 default values if not emacs:
55 55
56 apollo 56 apollo
57 BSD Real BSD, not just BSD-like. 57 BSD Real BSD, not just BSD-like.
58 convex
59 DGUX 58 DGUX
60 eunice UNIX emulator under VMS. 59 eunice UNIX emulator under VMS.
61 hpux 60 hpux
62 __MSDOS__ No-op for MSDOS. 61 __MSDOS__ No-op for MSDOS.
63 NeXT 62 NeXT
64 sgi 63 sgi
65 sequent Sequent Dynix 3.x.x (BSD)
66 _SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV)
67 sony_news NEWS-OS (works at least for 4.1C)
68 UMAX 64 UMAX
69 UMAX4_3 65 UMAX4_3
70 VMS 66 VMS
71 WINDOWS32 No-op for Windows95/NT. 67 _WIN32 Native Windows (possibly also defined on Cygwin)
72 __linux__ Linux: assumes /proc file system mounted. 68 __linux__, __ANDROID__ Linux: assumes /proc file system mounted.
73 Support from Michael K. Johnson. 69 Support from Michael K. Johnson.
74 __CYGWIN__ Cygwin emulates linux /proc/loadavg. 70 __CYGWIN__ Cygwin emulates linux /proc/loadavg.
75 __NetBSD__ NetBSD: assumes /kern file system mounted. 71 __NetBSD__ NetBSD: assumes /kern file system mounted.
@@ -97,9 +93,8 @@
97 93
98# include "intprops.h" 94# include "intprops.h"
99 95
100# if !defined (BSD) && defined (ultrix) 96# if defined _WIN32 && ! defined __CYGWIN__ && ! defined WINDOWS32
101/* Ultrix behaves like BSD on Vaxen. */ 97# define WINDOWS32
102# define BSD
103# endif 98# endif
104 99
105# ifdef NeXT 100# ifdef NeXT
@@ -141,10 +136,6 @@
141# define MORE_BSD 136# define MORE_BSD
142# endif 137# endif
143 138
144# if defined (ultrix) && defined (mips)
145# define decstation
146# endif
147
148# if defined (__SVR4) && !defined (SVR4) 139# if defined (__SVR4) && !defined (SVR4)
149# define SVR4 140# define SVR4
150# endif 141# endif
@@ -168,13 +159,6 @@
168# include <sys/table.h> 159# include <sys/table.h>
169# endif 160# endif
170 161
171/* UTek's /bin/cc on the 4300 has no architecture specific cpp define by
172 default, but _MACH_IND_SYS_TYPES is defined in <sys/types.h>. Combine
173 that with a couple of other things and we'll have a unique match. */
174# if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES)
175# define tek4300 /* Define by emacs, but not by other users. */
176# endif
177
178 162
179/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ 163/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */
180# ifndef LOAD_AVE_TYPE 164# ifndef LOAD_AVE_TYPE
@@ -187,14 +171,6 @@
187# define LOAD_AVE_TYPE long 171# define LOAD_AVE_TYPE long
188# endif 172# endif
189 173
190# ifdef decstation
191# define LOAD_AVE_TYPE long
192# endif
193
194# ifdef _SEQUENT_
195# define LOAD_AVE_TYPE long
196# endif
197
198# ifdef sgi 174# ifdef sgi
199# define LOAD_AVE_TYPE long 175# define LOAD_AVE_TYPE long
200# endif 176# endif
@@ -203,41 +179,14 @@
203# define LOAD_AVE_TYPE long 179# define LOAD_AVE_TYPE long
204# endif 180# endif
205 181
206# ifdef sony_news
207# define LOAD_AVE_TYPE long
208# endif
209
210# ifdef sequent
211# define LOAD_AVE_TYPE long
212# endif
213
214# ifdef OSF_ALPHA 182# ifdef OSF_ALPHA
215# define LOAD_AVE_TYPE long 183# define LOAD_AVE_TYPE long
216# endif 184# endif
217 185
218# if defined (ardent) && defined (titan)
219# define LOAD_AVE_TYPE long
220# endif
221
222# ifdef tek4300
223# define LOAD_AVE_TYPE long
224# endif
225
226# if defined (alliant) && defined (i860) /* Alliant FX/2800 */
227# define LOAD_AVE_TYPE long
228# endif
229
230# if defined _AIX && ! defined HAVE_LIBPERFSTAT 186# if defined _AIX && ! defined HAVE_LIBPERFSTAT
231# define LOAD_AVE_TYPE long 187# define LOAD_AVE_TYPE long
232# endif 188# endif
233 189
234# ifdef convex
235# define LOAD_AVE_TYPE double
236# ifndef LDAV_CVT
237# define LDAV_CVT(n) (n)
238# endif
239# endif
240
241# endif /* No LOAD_AVE_TYPE. */ 190# endif /* No LOAD_AVE_TYPE. */
242 191
243# ifdef OSF_ALPHA 192# ifdef OSF_ALPHA
@@ -247,13 +196,6 @@
247# define FSCALE 1024.0 196# define FSCALE 1024.0
248# endif 197# endif
249 198
250# if defined (alliant) && defined (i860) /* Alliant FX/2800 */
251/* <sys/param.h> defines an incorrect value for FSCALE on an
252 Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */
253# undef FSCALE
254# define FSCALE 100.0
255# endif
256
257 199
258# ifndef FSCALE 200# ifndef FSCALE
259 201
@@ -263,25 +205,17 @@
263# define FSCALE 2048.0 205# define FSCALE 2048.0
264# endif 206# endif
265 207
266# if defined (MIPS) || defined (SVR4) || defined (decstation) 208# if defined (MIPS) || defined (SVR4)
267# define FSCALE 256 209# define FSCALE 256
268# endif 210# endif
269 211
270# if defined (sgi) || defined (sequent) 212# if defined (sgi)
271/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined 213/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined
272 above under #ifdef MIPS. But we want the sgi value. */ 214 above under #ifdef MIPS. But we want the sgi value. */
273# undef FSCALE 215# undef FSCALE
274# define FSCALE 1000.0 216# define FSCALE 1000.0
275# endif 217# endif
276 218
277# if defined (ardent) && defined (titan)
278# define FSCALE 65536.0
279# endif
280
281# ifdef tek4300
282# define FSCALE 100.0
283# endif
284
285# if defined _AIX && !defined HAVE_LIBPERFSTAT 219# if defined _AIX && !defined HAVE_LIBPERFSTAT
286# define FSCALE 65536.0 220# define FSCALE 65536.0
287# endif 221# endif
@@ -303,28 +237,22 @@
303# endif 237# endif
304 238
305 239
306# if !defined (KERNEL_FILE) && defined (sequent)
307# define KERNEL_FILE "/dynix"
308# endif
309
310# if !defined (KERNEL_FILE) && defined (hpux) 240# if !defined (KERNEL_FILE) && defined (hpux)
311# define KERNEL_FILE "/hp-ux" 241# define KERNEL_FILE "/hp-ux"
312# endif 242# endif
313 243
314# if !defined (KERNEL_FILE) && (defined (_SEQUENT_) || defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan))) 244# if !defined (KERNEL_FILE) && (defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi))
315# define KERNEL_FILE "/unix" 245# define KERNEL_FILE "/unix"
316# endif 246# endif
317 247
318 248
319# if !defined (LDAV_SYMBOL) && defined (alliant) 249# if !defined (LDAV_SYMBOL) && (defined (hpux) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (_AIX) && !defined(HAVE_LIBPERFSTAT)))
320# define LDAV_SYMBOL "_Loadavg"
321# endif
322
323# if !defined (LDAV_SYMBOL) && ((defined (hpux) && !defined (hp9000s300)) || defined (_SEQUENT_) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan)) || (defined (_AIX) && !defined(HAVE_LIBPERFSTAT)))
324# define LDAV_SYMBOL "avenrun" 250# define LDAV_SYMBOL "avenrun"
325# endif 251# endif
326 252
327# include <unistd.h> 253# ifdef HAVE_UNISTD_H
254# include <unistd.h>
255# endif
328 256
329/* LOAD_AVE_TYPE should only get defined if we're going to use the 257/* LOAD_AVE_TYPE should only get defined if we're going to use the
330 nlist method. */ 258 nlist method. */
@@ -335,7 +263,7 @@
335# ifdef LOAD_AVE_TYPE 263# ifdef LOAD_AVE_TYPE
336 264
337# ifndef __VMS 265# ifndef __VMS
338# ifndef __linux__ 266# if !(defined __linux__ || defined __ANDROID__)
339# ifndef NLIST_STRUCT 267# ifndef NLIST_STRUCT
340# include <a.out.h> 268# include <a.out.h>
341# else /* NLIST_STRUCT */ 269# else /* NLIST_STRUCT */
@@ -358,7 +286,7 @@
358# ifndef LDAV_SYMBOL 286# ifndef LDAV_SYMBOL
359# define LDAV_SYMBOL "_avenrun" 287# define LDAV_SYMBOL "_avenrun"
360# endif /* LDAV_SYMBOL */ 288# endif /* LDAV_SYMBOL */
361# endif /* __linux__ */ 289# endif /* __linux__ || __ANDROID__ */
362 290
363# else /* __VMS */ 291# else /* __VMS */
364 292
@@ -431,7 +359,8 @@
431# include <sys/dg_sys_info.h> 359# include <sys/dg_sys_info.h>
432# endif 360# endif
433 361
434# if (defined __linux__ || defined __CYGWIN__ || defined SUNOS_5 \ 362# if (defined __linux__ || defined __ANDROID__ \
363 || defined __CYGWIN__ || defined SUNOS_5 \
435 || (defined LOAD_AVE_TYPE && ! defined __VMS)) 364 || (defined LOAD_AVE_TYPE && ! defined __VMS))
436# include <fcntl.h> 365# include <fcntl.h>
437# endif 366# endif
@@ -460,7 +389,7 @@ static bool getloadavg_initialized;
460/* Offset in kmem to seek to read load average, or 0 means invalid. */ 389/* Offset in kmem to seek to read load average, or 0 means invalid. */
461static long offset; 390static long offset;
462 391
463# if ! defined __VMS && ! defined sgi && ! defined __linux__ 392# if ! defined __VMS && ! defined sgi && ! (defined __linux__ || defined __ANDROID__)
464static struct nlist name_list[2]; 393static struct nlist name_list[2];
465# endif 394# endif
466 395
@@ -495,17 +424,17 @@ getloadavg (double loadavg[], int nelem)
495 int saved_errno; 424 int saved_errno;
496 425
497 kc = kstat_open (); 426 kc = kstat_open ();
498 if (kc == 0) 427 if (kc == NULL)
499 return -1; 428 return -1;
500 ksp = kstat_lookup (kc, "unix", 0, "system_misc"); 429 ksp = kstat_lookup (kc, "unix", 0, "system_misc");
501 if (ksp == 0) 430 if (ksp == NULL)
502 return -1; 431 return -1;
503 if (kstat_read (kc, ksp, 0) == -1) 432 if (kstat_read (kc, ksp, 0) == -1)
504 return -1; 433 return -1;
505 434
506 435
507 kn = kstat_data_lookup (ksp, "avenrun_1min"); 436 kn = kstat_data_lookup (ksp, "avenrun_1min");
508 if (kn == 0) 437 if (kn == NULL)
509 { 438 {
510 /* Return -1 if no load average information is available. */ 439 /* Return -1 if no load average information is available. */
511 nelem = 0; 440 nelem = 0;
@@ -518,14 +447,14 @@ getloadavg (double loadavg[], int nelem)
518 if (nelem >= 2) 447 if (nelem >= 2)
519 { 448 {
520 kn = kstat_data_lookup (ksp, "avenrun_5min"); 449 kn = kstat_data_lookup (ksp, "avenrun_5min");
521 if (kn != 0) 450 if (kn != NULL)
522 { 451 {
523 loadavg[elem++] = (double) kn->value.ul / FSCALE; 452 loadavg[elem++] = (double) kn->value.ul / FSCALE;
524 453
525 if (nelem >= 3) 454 if (nelem >= 3)
526 { 455 {
527 kn = kstat_data_lookup (ksp, "avenrun_15min"); 456 kn = kstat_data_lookup (ksp, "avenrun_15min");
528 if (kn != 0) 457 if (kn != NULL)
529 loadavg[elem++] = (double) kn->value.ul / FSCALE; 458 loadavg[elem++] = (double) kn->value.ul / FSCALE;
530 } 459 }
531 } 460 }
@@ -570,8 +499,8 @@ getloadavg (double loadavg[], int nelem)
570 } 499 }
571# endif 500# endif
572 501
573# if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__)) 502# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__ || defined __CYGWIN__)
574 /* Linux without glibc, Cygwin */ 503 /* Linux without glibc, Android, Cygwin */
575# define LDAV_DONE 504# define LDAV_DONE
576# undef LOAD_AVE_TYPE 505# undef LOAD_AVE_TYPE
577 506
@@ -583,7 +512,7 @@ getloadavg (double loadavg[], int nelem)
583 char const *ptr = ldavgbuf; 512 char const *ptr = ldavgbuf;
584 int fd, count, saved_errno; 513 int fd, count, saved_errno;
585 514
586 fd = open (LINUX_LDAV_FILE, O_RDONLY); 515 fd = open (LINUX_LDAV_FILE, O_RDONLY | O_CLOEXEC);
587 if (fd == -1) 516 if (fd == -1)
588 return -1; 517 return -1;
589 count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); 518 count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
@@ -621,12 +550,12 @@ getloadavg (double loadavg[], int nelem)
621 for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++) 550 for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++)
622 numerator = 10 * numerator + (*ptr - '0'), denominator *= 10; 551 numerator = 10 * numerator + (*ptr - '0'), denominator *= 10;
623 552
624 loadavg[elem++] = numerator / denominator; 553 loadavg[elem] = numerator / denominator;
625 } 554 }
626 555
627 return elem; 556 return elem;
628 557
629# endif /* __linux__ || __CYGWIN__ */ 558# endif /* __linux__ || __ANDROID__ || __CYGWIN__ */
630 559
631# if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ 560# if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */
632# define LDAV_DONE 561# define LDAV_DONE
@@ -638,15 +567,22 @@ getloadavg (double loadavg[], int nelem)
638 567
639 unsigned long int load_ave[3], scale; 568 unsigned long int load_ave[3], scale;
640 int count; 569 int count;
641 FILE *fp; 570 char readbuf[4 * INT_BUFSIZE_BOUND (unsigned long int) + 1];
642 571 int fd = open (NETBSD_LDAV_FILE, O_RDONLY | O_CLOEXEC);
643 fp = fopen (NETBSD_LDAV_FILE, "r"); 572 if (fd < 0)
644 if (fp == NULL) 573 return fd;
645 return -1; 574 int nread = read (fd, readbuf, sizeof readbuf - 1);
646 count = fscanf (fp, "%lu %lu %lu %lu\n", 575 int err = errno;
576 close (fd);
577 if (nread < 0)
578 {
579 errno = err;
580 return -1;
581 }
582 readbuf[nread] = '\0';
583 count = sscanf (readbuf, "%lu %lu %lu %lu\n",
647 &load_ave[0], &load_ave[1], &load_ave[2], 584 &load_ave[0], &load_ave[1], &load_ave[2],
648 &scale); 585 &scale);
649 (void) fclose (fp);
650 if (count != 4) 586 if (count != 4)
651 { 587 {
652 errno = ENOTSUP; 588 errno = ENOTSUP;
@@ -915,7 +851,7 @@ getloadavg (double loadavg[], int nelem)
915 851
916# ifndef SUNOS_5 852# ifndef SUNOS_5
917 if ( 853 if (
918# if !(defined (_AIX) && !defined (ps2)) 854# if !defined (_AIX)
919 nlist (KERNEL_FILE, name_list) 855 nlist (KERNEL_FILE, name_list)
920# else /* _AIX */ 856# else /* _AIX */
921 knlist (name_list, 1, sizeof (name_list[0])) 857 knlist (name_list, 1, sizeof (name_list[0]))
@@ -940,33 +876,17 @@ getloadavg (double loadavg[], int nelem)
940 if (!getloadavg_initialized) 876 if (!getloadavg_initialized)
941 { 877 {
942# ifndef SUNOS_5 878# ifndef SUNOS_5
943 /* Set the channel to close on exec, so it does not
944 litter any child's descriptor table. */
945# ifndef O_CLOEXEC
946# define O_CLOEXEC 0
947# endif
948 int fd = open ("/dev/kmem", O_RDONLY | O_CLOEXEC); 879 int fd = open ("/dev/kmem", O_RDONLY | O_CLOEXEC);
949 if (0 <= fd) 880 if (0 <= fd)
950 { 881 {
951# if F_DUPFD_CLOEXEC 882 channel = fd;
952 if (fd <= STDERR_FILENO) 883 getloadavg_initialized = true;
953 {
954 int fd1 = fcntl (fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1);
955 close (fd);
956 fd = fd1;
957 }
958# endif
959 if (0 <= fd)
960 {
961 channel = fd;
962 getloadavg_initialized = true;
963 }
964 } 884 }
965# else /* SUNOS_5 */ 885# else /* SUNOS_5 */
966 /* We pass 0 for the kernel, corefile, and swapfile names 886 /* We pass 0 for the kernel, corefile, and swapfile names
967 to use the currently running kernel. */ 887 to use the currently running kernel. */
968 kd = kvm_open (0, 0, 0, O_RDONLY, 0); 888 kd = kvm_open (0, 0, 0, O_RDONLY, 0);
969 if (kd != 0) 889 if (kd != NULL)
970 { 890 {
971 /* nlist the currently running kernel. */ 891 /* nlist the currently running kernel. */
972 kvm_nlist (kd, name_list); 892 kvm_nlist (kd, name_list);