summaryrefslogtreecommitdiffstats
path: root/lib/getloadavg.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/getloadavg.c')
-rw-r--r--lib/getloadavg.c166
1 files changed, 56 insertions, 110 deletions
diff --git a/lib/getloadavg.c b/lib/getloadavg.c
index e9c4c08..c6b6fee 100644
--- a/lib/getloadavg.c
+++ b/lib/getloadavg.c
@@ -1,6 +1,10 @@
1/* Get the system load averages. 1/* Get the system load averages.
2 Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994, 1995, 1997 2
3 Free Software Foundation, Inc. 3 Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994,
4 1995, 1997, 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
5
6 NOTE: The canonical source of this file is maintained with gnulib.
7 Bugs can be reported to bug-gnulib@gnu.org.
4 8
5 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
6 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
@@ -35,12 +39,17 @@
35 LOAD_AVE_TYPE Type of the load average array in the kernel. 39 LOAD_AVE_TYPE Type of the load average array in the kernel.
36 Must be defined unless one of 40 Must be defined unless one of
37 apollo, DGUX, NeXT, or UMAX is defined; 41 apollo, DGUX, NeXT, or UMAX is defined;
42 or we have libkstat;
38 otherwise, no load average is available. 43 otherwise, no load average is available.
44 HAVE_NLIST_H nlist.h is available. NLIST_STRUCT defaults
45 to this.
39 NLIST_STRUCT Include nlist.h, not a.out.h, and 46 NLIST_STRUCT Include nlist.h, not a.out.h, and
40 the nlist n_name element is a pointer, 47 the nlist n_name element is a pointer,
41 not an array. 48 not an array.
42 NLIST_NAME_UNION struct nlist has an n_un member, not n_name. 49 HAVE_STRUCT_NLIST_N_UN_N_NAME `n_un.n_name' is member of `struct nlist'.
43 LINUX_LDAV_FILE [__linux__]: File containing load averages. 50 LINUX_LDAV_FILE [__linux__]: File containing load averages.
51 HAVE_LOCALE_H locale.h is available.
52 HAVE_SETLOCALE The `setlocale' function is available.
44 53
45 Specific system predefines this file uses, aside from setting 54 Specific system predefines this file uses, aside from setting
46 default values if not emacs: 55 default values if not emacs:
@@ -62,7 +71,7 @@
62 VMS 71 VMS
63 WINDOWS32 No-op for Windows95/NT. 72 WINDOWS32 No-op for Windows95/NT.
64 __linux__ Linux: assumes /proc filesystem mounted. 73 __linux__ Linux: assumes /proc filesystem mounted.
65 Support from Michael K. Johnson. 74 Support from Michael K. Johnson.
66 __NetBSD__ NetBSD: assumes /kern filesystem mounted. 75 __NetBSD__ NetBSD: assumes /kern filesystem mounted.
67 76
68 In addition, to avoid nesting many #ifdefs, we internally set 77 In addition, to avoid nesting many #ifdefs, we internally set
@@ -81,7 +90,7 @@
81/* Both the Emacs and non-Emacs sections want this. Some 90/* Both the Emacs and non-Emacs sections want this. Some
82 configuration files' definitions for the LOAD_AVE_CVT macro (like 91 configuration files' definitions for the LOAD_AVE_CVT macro (like
83 sparc.h's) use macros like FSCALE, defined here. */ 92 sparc.h's) use macros like FSCALE, defined here. */
84#ifdef unix 93#if defined (unix) || defined (__unix)
85# include <sys/param.h> 94# include <sys/param.h>
86#endif 95#endif
87 96
@@ -98,13 +107,15 @@
98extern int errno; 107extern int errno;
99#endif 108#endif
100 109
101#if HAVE_LOCALE_H 110#ifdef HAVE_LOCALE_H
102# include <locale.h> 111# include <locale.h>
103#endif 112#endif
104#if !HAVE_SETLOCALE 113#ifndef HAVE_SETLOCALE
105# define setlocale(Category, Locale) /* empty */ 114# define setlocale(Category, Locale) /* empty */
106#endif 115#endif
107 116
117#include "cloexec.h"
118
108#ifndef HAVE_GETLOADAVG 119#ifndef HAVE_GETLOADAVG
109 120
110/* The existing Emacs configuration files define a macro called 121/* The existing Emacs configuration files define a macro called
@@ -117,7 +128,7 @@ extern int errno;
117 LOAD_AVE_CVT, but future machine config files should just define 128 LOAD_AVE_CVT, but future machine config files should just define
118 LDAV_CVT directly. */ 129 LDAV_CVT directly. */
119 130
120# if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT) 131# if !defined (LDAV_CVT) && defined (LOAD_AVE_CVT)
121# define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0) 132# define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0)
122# endif 133# endif
123 134
@@ -137,6 +148,12 @@ extern int errno;
137# undef FSCALE 148# undef FSCALE
138# endif 149# endif
139 150
151/* Same issues as for NeXT apply to the HURD-based GNU system. */
152# ifdef __GNU__
153# undef BSD
154# undef FSCALE
155# endif /* __GNU__ */
156
140/* Set values that are different from the defaults, which are 157/* Set values that are different from the defaults, which are
141 set a little farther down with #ifndef. */ 158 set a little farther down with #ifndef. */
142 159
@@ -155,11 +172,11 @@ extern int errno;
155# define sun 172# define sun
156# endif 173# endif
157 174
158# if defined(hp300) && !defined(hpux) 175# if defined (hp300) && !defined (hpux)
159# define MORE_BSD 176# define MORE_BSD
160# endif 177# endif
161 178
162# if defined(ultrix) && defined(mips) 179# if defined (ultrix) && defined (mips)
163# define decstation 180# define decstation
164# endif 181# endif
165 182
@@ -167,7 +184,7 @@ extern int errno;
167# define SVR4 184# define SVR4
168# endif 185# endif
169 186
170# if (defined(sun) && defined(SVR4)) || defined (SOLARIS2) 187# if (defined (sun) && defined (SVR4)) || defined (SOLARIS2)
171# define SUNOS_5 188# define SUNOS_5
172# endif 189# endif
173 190
@@ -239,7 +256,7 @@ extern int errno;
239# define LOAD_AVE_TYPE long 256# define LOAD_AVE_TYPE long
240# endif 257# endif
241 258
242# if defined(alliant) && defined(i860) /* Alliant FX/2800 */ 259# if defined (alliant) && defined (i860) /* Alliant FX/2800 */
243# define LOAD_AVE_TYPE long 260# define LOAD_AVE_TYPE long
244# endif 261# endif
245 262
@@ -263,7 +280,7 @@ extern int errno;
263# define FSCALE 1024.0 280# define FSCALE 1024.0
264# endif 281# endif
265 282
266# if defined(alliant) && defined(i860) /* Alliant FX/2800 */ 283# if defined (alliant) && defined (i860) /* Alliant FX/2800 */
267/* <sys/param.h> defines an incorrect value for FSCALE on an 284/* <sys/param.h> defines an incorrect value for FSCALE on an
268 Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */ 285 Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */
269# undef FSCALE 286# undef FSCALE
@@ -279,7 +296,7 @@ extern int errno;
279# define FSCALE 2048.0 296# define FSCALE 2048.0
280# endif 297# endif
281 298
282# if defined(MIPS) || defined(SVR4) || defined(decstation) 299# if defined (MIPS) || defined (SVR4) || defined (decstation)
283# define FSCALE 256 300# define FSCALE 256
284# endif 301# endif
285 302
@@ -314,69 +331,7 @@ extern int errno;
314# endif 331# endif
315# endif 332# endif
316 333
317/* VAX C can't handle multi-line #ifs, or lines longer that 256 characters. */ 334# if defined (sgi) || (defined (mips) && !defined (BSD))
318# ifndef NLIST_STRUCT
319
320# ifdef MORE_BSD
321# define NLIST_STRUCT
322# endif
323
324# ifdef sun
325# define NLIST_STRUCT
326# endif
327
328# ifdef decstation
329# define NLIST_STRUCT
330# endif
331
332# ifdef hpux
333# define NLIST_STRUCT
334# endif
335
336# if defined (_SEQUENT_) || defined (sequent)
337# define NLIST_STRUCT
338# endif
339
340# ifdef sgi
341# define NLIST_STRUCT
342# endif
343
344# ifdef SVR4
345# define NLIST_STRUCT
346# endif
347
348# ifdef sony_news
349# define NLIST_STRUCT
350# endif
351
352# ifdef OSF_ALPHA
353# define NLIST_STRUCT
354# endif
355
356# if defined (ardent) && defined (titan)
357# define NLIST_STRUCT
358# endif
359
360# ifdef tek4300
361# define NLIST_STRUCT
362# endif
363
364# ifdef butterfly
365# define NLIST_STRUCT
366# endif
367
368# if defined(alliant) && defined(i860) /* Alliant FX/2800 */
369# define NLIST_STRUCT
370# endif
371
372# ifdef _AIX
373# define NLIST_STRUCT
374# endif
375
376# endif /* defined (NLIST_STRUCT) */
377
378
379# if defined(sgi) || (defined(mips) && !defined(BSD))
380# define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31)) 335# define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31))
381# endif 336# endif
382 337
@@ -389,7 +344,7 @@ extern int errno;
389# define KERNEL_FILE "/hp-ux" 344# define KERNEL_FILE "/hp-ux"
390# endif 345# endif
391 346
392# if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || (defined (ardent) && defined (titan))) 347# if !defined (KERNEL_FILE) && (defined (_SEQUENT_) || defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan)))
393# define KERNEL_FILE "/unix" 348# define KERNEL_FILE "/unix"
394# endif 349# endif
395 350
@@ -398,7 +353,7 @@ extern int errno;
398# define LDAV_SYMBOL "_Loadavg" 353# define LDAV_SYMBOL "_Loadavg"
399# endif 354# endif
400 355
401# if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX)) 356# if !defined (LDAV_SYMBOL) && ((defined (hpux) && !defined (hp9000s300)) || defined (_SEQUENT_) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan)) || defined (_AIX))
402# define LDAV_SYMBOL "avenrun" 357# define LDAV_SYMBOL "avenrun"
403# endif 358# endif
404 359
@@ -410,7 +365,7 @@ extern int errno;
410 365
411/* LOAD_AVE_TYPE should only get defined if we're going to use the 366/* LOAD_AVE_TYPE should only get defined if we're going to use the
412 nlist method. */ 367 nlist method. */
413# if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL)) 368# if !defined (LOAD_AVE_TYPE) && (defined (BSD) || defined (LDAV_CVT) || defined (KERNEL_FILE) || defined (LDAV_SYMBOL))
414# define LOAD_AVE_TYPE double 369# define LOAD_AVE_TYPE double
415# endif 370# endif
416 371
@@ -459,7 +414,7 @@ extern int errno;
459 414
460# endif /* LOAD_AVE_TYPE */ 415# endif /* LOAD_AVE_TYPE */
461 416
462# if defined(__GNU__) && !defined (NeXT) 417# if defined (__GNU__) && !defined (NeXT)
463/* Note that NeXT Openstep defines __GNU__ even though it should not. */ 418/* Note that NeXT Openstep defines __GNU__ even though it should not. */
464/* GNU system acts much like NeXT, for load average purposes, 419/* GNU system acts much like NeXT, for load average purposes,
465 but not exactly. */ 420 but not exactly. */
@@ -506,7 +461,7 @@ extern int errno;
506# include <sys/dg_sys_info.h> 461# include <sys/dg_sys_info.h>
507# endif 462# endif
508 463
509# if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION) 464# if defined (HAVE_FCNTL_H) || defined (_POSIX_VERSION)
510# include <fcntl.h> 465# include <fcntl.h>
511# else 466# else
512# include <sys/file.h> 467# include <sys/file.h>
@@ -528,7 +483,7 @@ static unsigned int samples;
528static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */ 483static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */
529# endif /* DGUX */ 484# endif /* DGUX */
530 485
531# ifdef LOAD_AVE_TYPE 486# if !defined (HAVE_LIBKSTAT) && defined (LOAD_AVE_TYPE)
532/* File descriptor open to /dev/kmem or VMS load ave driver. */ 487/* File descriptor open to /dev/kmem or VMS load ave driver. */
533static int channel; 488static int channel;
534/* Nonzero iff channel is valid. */ 489/* Nonzero iff channel is valid. */
@@ -536,7 +491,7 @@ static int getloadavg_initialized;
536/* Offset in kmem to seek to read load average, or 0 means invalid. */ 491/* Offset in kmem to seek to read load average, or 0 means invalid. */
537static long offset; 492static long offset;
538 493
539# if !defined(VMS) && !defined(sgi) && !defined(__linux__) 494# if !defined (VMS) && !defined (sgi) && !defined (__linux__)
540static struct nlist nl[2]; 495static struct nlist nl[2];
541# endif /* Not VMS or sgi */ 496# endif /* Not VMS or sgi */
542 497
@@ -544,7 +499,7 @@ static struct nlist nl[2];
544static kvm_t *kd; 499static kvm_t *kd;
545# endif /* SUNOS_5 */ 500# endif /* SUNOS_5 */
546 501
547# endif /* LOAD_AVE_TYPE */ 502# endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */
548 503
549/* Put the 1 minute, 5 minute and 15 minute load averages 504/* Put the 1 minute, 5 minute and 15 minute load averages
550 into the first NELEM elements of LOADAVG. 505 into the first NELEM elements of LOADAVG.
@@ -552,9 +507,7 @@ static kvm_t *kd;
552 or -1 if an error occurred. */ 507 or -1 if an error occurred. */
553 508
554int 509int
555getloadavg (loadavg, nelem) 510getloadavg (double loadavg[], int nelem)
556 double loadavg[];
557 int nelem;
558{ 511{
559 int elem = 0; /* Return value. */ 512 int elem = 0; /* Return value. */
560 513
@@ -577,7 +530,7 @@ getloadavg (loadavg, nelem)
577 if (kc == 0) 530 if (kc == 0)
578 return -1; 531 return -1;
579 ksp = kstat_lookup (kc, "unix", 0, "system_misc"); 532 ksp = kstat_lookup (kc, "unix", 0, "system_misc");
580 if (ksp == 0 ) 533 if (ksp == 0)
581 return -1; 534 return -1;
582 if (kstat_read (kc, ksp, 0) == -1) 535 if (kstat_read (kc, ksp, 0) == -1)
583 return -1; 536 return -1;
@@ -592,20 +545,20 @@ getloadavg (loadavg, nelem)
592 } 545 }
593 546
594 if (nelem >= 1) 547 if (nelem >= 1)
595 loadavg[elem++] = (double) kn->value.ul/FSCALE; 548 loadavg[elem++] = (double) kn->value.ul / FSCALE;
596 549
597 if (nelem >= 2) 550 if (nelem >= 2)
598 { 551 {
599 kn = kstat_data_lookup (ksp, "avenrun_5min"); 552 kn = kstat_data_lookup (ksp, "avenrun_5min");
600 if (kn != 0) 553 if (kn != 0)
601 { 554 {
602 loadavg[elem++] = (double) kn->value.ul/FSCALE; 555 loadavg[elem++] = (double) kn->value.ul / FSCALE;
603 556
604 if (nelem >= 3) 557 if (nelem >= 3)
605 { 558 {
606 kn = kstat_data_lookup (ksp, "avenrun_15min"); 559 kn = kstat_data_lookup (ksp, "avenrun_15min");
607 if (kn != 0) 560 if (kn != 0)
608 loadavg[elem++] = (double) kn->value.ul/FSCALE; 561 loadavg[elem++] = (double) kn->value.ul / FSCALE;
609 } 562 }
610 } 563 }
611 } 564 }
@@ -870,8 +823,8 @@ getloadavg (loadavg, nelem)
870 for (elem = 0; elem < nelem; elem++) 823 for (elem = 0; elem < nelem; elem++)
871 loadavg[elem] 824 loadavg[elem]
872 = (load_ave.tl_lscale == 0 825 = (load_ave.tl_lscale == 0
873 ? load_ave.tl_avenrun.d[elem] 826 ? load_ave.tl_avenrun.d[elem]
874 : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); 827 : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
875# endif /* OSF_ALPHA */ 828# endif /* OSF_ALPHA */
876 829
877# if !defined (LDAV_DONE) && defined (VMS) 830# if !defined (LDAV_DONE) && defined (VMS)
@@ -914,7 +867,7 @@ getloadavg (loadavg, nelem)
914 return -1; 867 return -1;
915# endif /* VMS */ 868# endif /* VMS */
916 869
917# if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS) 870# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) && !defined (VMS)
918 871
919 /* UNIX-specific code -- read the average from /dev/kmem. */ 872 /* UNIX-specific code -- read the average from /dev/kmem. */
920 873
@@ -930,13 +883,13 @@ getloadavg (loadavg, nelem)
930 strcpy (nl[0].n_name, LDAV_SYMBOL); 883 strcpy (nl[0].n_name, LDAV_SYMBOL);
931 strcpy (nl[1].n_name, ""); 884 strcpy (nl[1].n_name, "");
932# else /* NLIST_STRUCT */ 885# else /* NLIST_STRUCT */
933# ifdef NLIST_NAME_UNION 886# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
934 nl[0].n_un.n_name = LDAV_SYMBOL; 887 nl[0].n_un.n_name = LDAV_SYMBOL;
935 nl[1].n_un.n_name = 0; 888 nl[1].n_un.n_name = 0;
936# else /* not NLIST_NAME_UNION */ 889# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
937 nl[0].n_name = LDAV_SYMBOL; 890 nl[0].n_name = LDAV_SYMBOL;
938 nl[1].n_name = 0; 891 nl[1].n_name = 0;
939# endif /* not NLIST_NAME_UNION */ 892# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
940# endif /* NLIST_STRUCT */ 893# endif /* NLIST_STRUCT */
941 894
942# ifndef SUNOS_5 895# ifndef SUNOS_5
@@ -973,12 +926,7 @@ getloadavg (loadavg, nelem)
973 { 926 {
974 /* Set the channel to close on exec, so it does not 927 /* Set the channel to close on exec, so it does not
975 litter any child's descriptor table. */ 928 litter any child's descriptor table. */
976# ifdef FD_SETFD 929 set_cloexec_flag (channel, true);
977# ifndef FD_CLOEXEC
978# define FD_CLOEXEC 1
979# endif
980 (void) fcntl (channel, F_SETFD, FD_CLOEXEC);
981# endif
982 getloadavg_initialized = 1; 930 getloadavg_initialized = 1;
983 } 931 }
984# else /* SUNOS_5 */ 932# else /* SUNOS_5 */
@@ -1010,9 +958,9 @@ getloadavg (loadavg, nelem)
1010# else /* SUNOS_5 */ 958# else /* SUNOS_5 */
1011 if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) 959 if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
1012 != sizeof (load_ave)) 960 != sizeof (load_ave))
1013 { 961 {
1014 kvm_close (kd); 962 kvm_close (kd);
1015 getloadavg_initialized = 0; 963 getloadavg_initialized = 0;
1016 } 964 }
1017# endif /* SUNOS_5 */ 965# endif /* SUNOS_5 */
1018 } 966 }
@@ -1046,9 +994,7 @@ getloadavg (loadavg, nelem)
1046 994
1047#ifdef TEST 995#ifdef TEST
1048void 996void
1049main (argc, argv) 997main (int argc, char **argv)
1050 int argc;
1051 char **argv;
1052{ 998{
1053 int naptime = 0; 999 int naptime = 0;
1054 1000