summaryrefslogtreecommitdiffstats
path: root/gl/getloadavg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/getloadavg.c')
-rw-r--r--gl/getloadavg.c179
1 files changed, 49 insertions, 130 deletions
diff --git a/gl/getloadavg.c b/gl/getloadavg.c
index 6e22819..59b53e7 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-2023 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.
@@ -86,7 +82,6 @@
86#include <stdlib.h> 82#include <stdlib.h>
87 83
88#include <errno.h> 84#include <errno.h>
89#include <stdbool.h>
90#include <stdio.h> 85#include <stdio.h>
91 86
92# include <sys/types.h> 87# include <sys/types.h>
@@ -97,9 +92,8 @@
97 92
98# include "intprops.h" 93# include "intprops.h"
99 94
100# if !defined (BSD) && defined (ultrix) 95# if defined _WIN32 && ! defined __CYGWIN__ && ! defined WINDOWS32
101/* Ultrix behaves like BSD on Vaxen. */ 96# define WINDOWS32
102# define BSD
103# endif 97# endif
104 98
105# ifdef NeXT 99# ifdef NeXT
@@ -141,10 +135,6 @@
141# define MORE_BSD 135# define MORE_BSD
142# endif 136# endif
143 137
144# if defined (ultrix) && defined (mips)
145# define decstation
146# endif
147
148# if defined (__SVR4) && !defined (SVR4) 138# if defined (__SVR4) && !defined (SVR4)
149# define SVR4 139# define SVR4
150# endif 140# endif
@@ -168,13 +158,6 @@
168# include <sys/table.h> 158# include <sys/table.h>
169# endif 159# endif
170 160
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 161
179/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ 162/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */
180# ifndef LOAD_AVE_TYPE 163# ifndef LOAD_AVE_TYPE
@@ -187,14 +170,6 @@
187# define LOAD_AVE_TYPE long 170# define LOAD_AVE_TYPE long
188# endif 171# endif
189 172
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 173# ifdef sgi
199# define LOAD_AVE_TYPE long 174# define LOAD_AVE_TYPE long
200# endif 175# endif
@@ -203,41 +178,14 @@
203# define LOAD_AVE_TYPE long 178# define LOAD_AVE_TYPE long
204# endif 179# endif
205 180
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 181# ifdef OSF_ALPHA
215# define LOAD_AVE_TYPE long 182# define LOAD_AVE_TYPE long
216# endif 183# endif
217 184
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 185# if defined _AIX && ! defined HAVE_LIBPERFSTAT
231# define LOAD_AVE_TYPE long 186# define LOAD_AVE_TYPE long
232# endif 187# endif
233 188
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. */ 189# endif /* No LOAD_AVE_TYPE. */
242 190
243# ifdef OSF_ALPHA 191# ifdef OSF_ALPHA
@@ -247,13 +195,6 @@
247# define FSCALE 1024.0 195# define FSCALE 1024.0
248# endif 196# endif
249 197
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 198
258# ifndef FSCALE 199# ifndef FSCALE
259 200
@@ -263,25 +204,17 @@
263# define FSCALE 2048.0 204# define FSCALE 2048.0
264# endif 205# endif
265 206
266# if defined (MIPS) || defined (SVR4) || defined (decstation) 207# if defined (MIPS) || defined (SVR4)
267# define FSCALE 256 208# define FSCALE 256
268# endif 209# endif
269 210
270# if defined (sgi) || defined (sequent) 211# if defined (sgi)
271/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined 212/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined
272 above under #ifdef MIPS. But we want the sgi value. */ 213 above under #ifdef MIPS. But we want the sgi value. */
273# undef FSCALE 214# undef FSCALE
274# define FSCALE 1000.0 215# define FSCALE 1000.0
275# endif 216# endif
276 217
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 218# if defined _AIX && !defined HAVE_LIBPERFSTAT
286# define FSCALE 65536.0 219# define FSCALE 65536.0
287# endif 220# endif
@@ -303,28 +236,22 @@
303# endif 236# endif
304 237
305 238
306# if !defined (KERNEL_FILE) && defined (sequent)
307# define KERNEL_FILE "/dynix"
308# endif
309
310# if !defined (KERNEL_FILE) && defined (hpux) 239# if !defined (KERNEL_FILE) && defined (hpux)
311# define KERNEL_FILE "/hp-ux" 240# define KERNEL_FILE "/hp-ux"
312# endif 241# endif
313 242
314# if !defined (KERNEL_FILE) && (defined (_SEQUENT_) || defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan))) 243# if !defined (KERNEL_FILE) && (defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi))
315# define KERNEL_FILE "/unix" 244# define KERNEL_FILE "/unix"
316# endif 245# endif
317 246
318 247
319# if !defined (LDAV_SYMBOL) && defined (alliant) 248# 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" 249# define LDAV_SYMBOL "avenrun"
325# endif 250# endif
326 251
327# include <unistd.h> 252# ifdef HAVE_UNISTD_H
253# include <unistd.h>
254# endif
328 255
329/* LOAD_AVE_TYPE should only get defined if we're going to use the 256/* LOAD_AVE_TYPE should only get defined if we're going to use the
330 nlist method. */ 257 nlist method. */
@@ -335,7 +262,7 @@
335# ifdef LOAD_AVE_TYPE 262# ifdef LOAD_AVE_TYPE
336 263
337# ifndef __VMS 264# ifndef __VMS
338# ifndef __linux__ 265# if !(defined __linux__ || defined __ANDROID__)
339# ifndef NLIST_STRUCT 266# ifndef NLIST_STRUCT
340# include <a.out.h> 267# include <a.out.h>
341# else /* NLIST_STRUCT */ 268# else /* NLIST_STRUCT */
@@ -358,7 +285,7 @@
358# ifndef LDAV_SYMBOL 285# ifndef LDAV_SYMBOL
359# define LDAV_SYMBOL "_avenrun" 286# define LDAV_SYMBOL "_avenrun"
360# endif /* LDAV_SYMBOL */ 287# endif /* LDAV_SYMBOL */
361# endif /* __linux__ */ 288# endif /* __linux__ || __ANDROID__ */
362 289
363# else /* __VMS */ 290# else /* __VMS */
364 291
@@ -431,7 +358,8 @@
431# include <sys/dg_sys_info.h> 358# include <sys/dg_sys_info.h>
432# endif 359# endif
433 360
434# if (defined __linux__ || defined __CYGWIN__ || defined SUNOS_5 \ 361# if (defined __linux__ || defined __ANDROID__ \
362 || defined __CYGWIN__ || defined SUNOS_5 \
435 || (defined LOAD_AVE_TYPE && ! defined __VMS)) 363 || (defined LOAD_AVE_TYPE && ! defined __VMS))
436# include <fcntl.h> 364# include <fcntl.h>
437# endif 365# endif
@@ -460,7 +388,7 @@ static bool getloadavg_initialized;
460/* Offset in kmem to seek to read load average, or 0 means invalid. */ 388/* Offset in kmem to seek to read load average, or 0 means invalid. */
461static long offset; 389static long offset;
462 390
463# if ! defined __VMS && ! defined sgi && ! defined __linux__ 391# if ! defined __VMS && ! defined sgi && ! (defined __linux__ || defined __ANDROID__)
464static struct nlist name_list[2]; 392static struct nlist name_list[2];
465# endif 393# endif
466 394
@@ -495,17 +423,17 @@ getloadavg (double loadavg[], int nelem)
495 int saved_errno; 423 int saved_errno;
496 424
497 kc = kstat_open (); 425 kc = kstat_open ();
498 if (kc == 0) 426 if (kc == NULL)
499 return -1; 427 return -1;
500 ksp = kstat_lookup (kc, "unix", 0, "system_misc"); 428 ksp = kstat_lookup (kc, "unix", 0, "system_misc");
501 if (ksp == 0) 429 if (ksp == NULL)
502 return -1; 430 return -1;
503 if (kstat_read (kc, ksp, 0) == -1) 431 if (kstat_read (kc, ksp, 0) == -1)
504 return -1; 432 return -1;
505 433
506 434
507 kn = kstat_data_lookup (ksp, "avenrun_1min"); 435 kn = kstat_data_lookup (ksp, "avenrun_1min");
508 if (kn == 0) 436 if (kn == NULL)
509 { 437 {
510 /* Return -1 if no load average information is available. */ 438 /* Return -1 if no load average information is available. */
511 nelem = 0; 439 nelem = 0;
@@ -518,14 +446,14 @@ getloadavg (double loadavg[], int nelem)
518 if (nelem >= 2) 446 if (nelem >= 2)
519 { 447 {
520 kn = kstat_data_lookup (ksp, "avenrun_5min"); 448 kn = kstat_data_lookup (ksp, "avenrun_5min");
521 if (kn != 0) 449 if (kn != NULL)
522 { 450 {
523 loadavg[elem++] = (double) kn->value.ul / FSCALE; 451 loadavg[elem++] = (double) kn->value.ul / FSCALE;
524 452
525 if (nelem >= 3) 453 if (nelem >= 3)
526 { 454 {
527 kn = kstat_data_lookup (ksp, "avenrun_15min"); 455 kn = kstat_data_lookup (ksp, "avenrun_15min");
528 if (kn != 0) 456 if (kn != NULL)
529 loadavg[elem++] = (double) kn->value.ul / FSCALE; 457 loadavg[elem++] = (double) kn->value.ul / FSCALE;
530 } 458 }
531 } 459 }
@@ -570,8 +498,8 @@ getloadavg (double loadavg[], int nelem)
570 } 498 }
571# endif 499# endif
572 500
573# if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__)) 501# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__ || defined __CYGWIN__)
574 /* Linux without glibc, Cygwin */ 502 /* Linux without glibc, Android, Cygwin */
575# define LDAV_DONE 503# define LDAV_DONE
576# undef LOAD_AVE_TYPE 504# undef LOAD_AVE_TYPE
577 505
@@ -583,7 +511,7 @@ getloadavg (double loadavg[], int nelem)
583 char const *ptr = ldavgbuf; 511 char const *ptr = ldavgbuf;
584 int fd, count, saved_errno; 512 int fd, count, saved_errno;
585 513
586 fd = open (LINUX_LDAV_FILE, O_RDONLY); 514 fd = open (LINUX_LDAV_FILE, O_RDONLY | O_CLOEXEC);
587 if (fd == -1) 515 if (fd == -1)
588 return -1; 516 return -1;
589 count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); 517 count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
@@ -621,12 +549,12 @@ getloadavg (double loadavg[], int nelem)
621 for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++) 549 for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++)
622 numerator = 10 * numerator + (*ptr - '0'), denominator *= 10; 550 numerator = 10 * numerator + (*ptr - '0'), denominator *= 10;
623 551
624 loadavg[elem++] = numerator / denominator; 552 loadavg[elem] = numerator / denominator;
625 } 553 }
626 554
627 return elem; 555 return elem;
628 556
629# endif /* __linux__ || __CYGWIN__ */ 557# endif /* __linux__ || __ANDROID__ || __CYGWIN__ */
630 558
631# if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ 559# if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */
632# define LDAV_DONE 560# define LDAV_DONE
@@ -638,15 +566,22 @@ getloadavg (double loadavg[], int nelem)
638 566
639 unsigned long int load_ave[3], scale; 567 unsigned long int load_ave[3], scale;
640 int count; 568 int count;
641 FILE *fp; 569 char readbuf[4 * INT_BUFSIZE_BOUND (unsigned long int) + 1];
642 570 int fd = open (NETBSD_LDAV_FILE, O_RDONLY | O_CLOEXEC);
643 fp = fopen (NETBSD_LDAV_FILE, "r"); 571 if (fd < 0)
644 if (fp == NULL) 572 return fd;
645 return -1; 573 int nread = read (fd, readbuf, sizeof readbuf - 1);
646 count = fscanf (fp, "%lu %lu %lu %lu\n", 574 int err = errno;
575 close (fd);
576 if (nread < 0)
577 {
578 errno = err;
579 return -1;
580 }
581 readbuf[nread] = '\0';
582 count = sscanf (readbuf, "%lu %lu %lu %lu\n",
647 &load_ave[0], &load_ave[1], &load_ave[2], 583 &load_ave[0], &load_ave[1], &load_ave[2],
648 &scale); 584 &scale);
649 (void) fclose (fp);
650 if (count != 4) 585 if (count != 4)
651 { 586 {
652 errno = ENOTSUP; 587 errno = ENOTSUP;
@@ -915,7 +850,7 @@ getloadavg (double loadavg[], int nelem)
915 850
916# ifndef SUNOS_5 851# ifndef SUNOS_5
917 if ( 852 if (
918# if !(defined (_AIX) && !defined (ps2)) 853# if !defined (_AIX)
919 nlist (KERNEL_FILE, name_list) 854 nlist (KERNEL_FILE, name_list)
920# else /* _AIX */ 855# else /* _AIX */
921 knlist (name_list, 1, sizeof (name_list[0])) 856 knlist (name_list, 1, sizeof (name_list[0]))
@@ -940,33 +875,17 @@ getloadavg (double loadavg[], int nelem)
940 if (!getloadavg_initialized) 875 if (!getloadavg_initialized)
941 { 876 {
942# ifndef SUNOS_5 877# 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); 878 int fd = open ("/dev/kmem", O_RDONLY | O_CLOEXEC);
949 if (0 <= fd) 879 if (0 <= fd)
950 { 880 {
951# if F_DUPFD_CLOEXEC 881 channel = fd;
952 if (fd <= STDERR_FILENO) 882 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 } 883 }
965# else /* SUNOS_5 */ 884# else /* SUNOS_5 */
966 /* We pass 0 for the kernel, corefile, and swapfile names 885 /* We pass 0 for the kernel, corefile, and swapfile names
967 to use the currently running kernel. */ 886 to use the currently running kernel. */
968 kd = kvm_open (0, 0, 0, O_RDONLY, 0); 887 kd = kvm_open (0, 0, 0, O_RDONLY, 0);
969 if (kd != 0) 888 if (kd != NULL)
970 { 889 {
971 /* nlist the currently running kernel. */ 890 /* nlist the currently running kernel. */
972 kvm_nlist (kd, name_list); 891 kvm_nlist (kd, name_list);