diff options
Diffstat (limited to 'lib/getloadavg.c')
-rw-r--r-- | lib/getloadavg.c | 149 |
1 files changed, 67 insertions, 82 deletions
diff --git a/lib/getloadavg.c b/lib/getloadavg.c index c6b6fee1..2a501314 100644 --- a/lib/getloadavg.c +++ b/lib/getloadavg.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Get the system load averages. | 1 | /* Get the system load averages. |
2 | 2 | ||
3 | Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, | 3 | Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, |
4 | 1995, 1997, 1999, 2000, 2003, 2004 Free Software Foundation, Inc. | 4 | 1995, 1997, 1999, 2000, 2003, 2004, 2005 Free Software 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. |
7 | Bugs can be reported to bug-gnulib@gnu.org. | 7 | Bugs can be reported to bug-gnulib@gnu.org. |
@@ -18,7 +18,7 @@ | |||
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, write to the Free Software | 20 | along with this program; if not, write to the Free Software |
21 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | 21 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
22 | USA. */ | 22 | USA. */ |
23 | 23 | ||
24 | /* Compile-time symbols that this file uses: | 24 | /* Compile-time symbols that this file uses: |
@@ -32,7 +32,7 @@ | |||
32 | AC_CHECK_FUNCS(pstat_getdynamic) in your | 32 | AC_CHECK_FUNCS(pstat_getdynamic) in your |
33 | configure.in file. | 33 | configure.in file. |
34 | FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. | 34 | FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. |
35 | KERNEL_FILE Pathname of the kernel to nlist. | 35 | KERNEL_FILE Name of the kernel file to nlist. |
36 | LDAV_CVT() Scale the load average from the kernel. | 36 | LDAV_CVT() Scale the load average from the kernel. |
37 | Returns a double. | 37 | Returns a double. |
38 | LDAV_SYMBOL Name of kernel symbol giving load average. | 38 | LDAV_SYMBOL Name of kernel symbol giving load average. |
@@ -47,9 +47,8 @@ | |||
47 | the nlist n_name element is a pointer, | 47 | 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__]: File containing load averages. | 50 | LINUX_LDAV_FILE [__linux__, __CYGWIN__]: File containing |
51 | HAVE_LOCALE_H locale.h is available. | 51 | load averages. |
52 | HAVE_SETLOCALE The `setlocale' function is available. | ||
53 | 52 | ||
54 | Specific system predefines this file uses, aside from setting | 53 | Specific system predefines this file uses, aside from setting |
55 | default values if not emacs: | 54 | default values if not emacs: |
@@ -70,9 +69,10 @@ | |||
70 | UMAX4_3 | 69 | UMAX4_3 |
71 | VMS | 70 | VMS |
72 | WINDOWS32 No-op for Windows95/NT. | 71 | WINDOWS32 No-op for Windows95/NT. |
73 | __linux__ Linux: assumes /proc filesystem mounted. | 72 | __linux__ Linux: assumes /proc file system mounted. |
74 | Support from Michael K. Johnson. | 73 | Support from Michael K. Johnson. |
75 | __NetBSD__ NetBSD: assumes /kern filesystem mounted. | 74 | __CYGWIN__ Cygwin emulates linux /proc/loadavg. |
75 | __NetBSD__ NetBSD: assumes /kern file system mounted. | ||
76 | 76 | ||
77 | In addition, to avoid nesting many #ifdefs, we internally set | 77 | In addition, to avoid nesting many #ifdefs, we internally set |
78 | LDAV_DONE to indicate that the load average has been computed. | 78 | LDAV_DONE to indicate that the load average has been computed. |
@@ -85,38 +85,29 @@ | |||
85 | # include <config.h> | 85 | # include <config.h> |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | #include <sys/types.h> | 88 | #include <errno.h> |
89 | 89 | #include <stdbool.h> | |
90 | /* Both the Emacs and non-Emacs sections want this. Some | 90 | #include <stdio.h> |
91 | configuration files' definitions for the LOAD_AVE_CVT macro (like | 91 | #include <stdlib.h> |
92 | sparc.h's) use macros like FSCALE, defined here. */ | ||
93 | #if defined (unix) || defined (__unix) | ||
94 | # include <sys/param.h> | ||
95 | #endif | ||
96 | |||
97 | 92 | ||
98 | /* Exclude all the code except the test program at the end | 93 | /* Exclude all the code except the test program at the end |
99 | if the system has its own `getloadavg' function. | 94 | if the system has its own `getloadavg' function. */ |
100 | 95 | ||
101 | The declaration of `errno' is needed by the test program | 96 | #ifndef HAVE_GETLOADAVG |
102 | as well as the function itself, so it comes first. */ | ||
103 | |||
104 | #include <errno.h> | ||
105 | |||
106 | #ifndef errno | ||
107 | extern int errno; | ||
108 | #endif | ||
109 | 97 | ||
110 | #ifdef HAVE_LOCALE_H | 98 | # include <sys/types.h> |
111 | # include <locale.h> | ||
112 | #endif | ||
113 | #ifndef HAVE_SETLOCALE | ||
114 | # define setlocale(Category, Locale) /* empty */ | ||
115 | #endif | ||
116 | 99 | ||
117 | #include "cloexec.h" | 100 | /* Both the Emacs and non-Emacs sections want this. Some |
101 | configuration files' definitions for the LOAD_AVE_CVT macro (like | ||
102 | sparc.h's) use macros like FSCALE, defined here. */ | ||
103 | # if defined (unix) || defined (__unix) | ||
104 | # include <sys/param.h> | ||
105 | # endif | ||
118 | 106 | ||
119 | #ifndef HAVE_GETLOADAVG | 107 | # include "c-strtod.h" |
108 | # include "cloexec.h" | ||
109 | # include "intprops.h" | ||
110 | # include "xalloc.h" | ||
120 | 111 | ||
121 | /* The existing Emacs configuration files define a macro called | 112 | /* The existing Emacs configuration files define a macro called |
122 | LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and | 113 | LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and |
@@ -357,11 +348,7 @@ extern int errno; | |||
357 | # define LDAV_SYMBOL "avenrun" | 348 | # define LDAV_SYMBOL "avenrun" |
358 | # endif | 349 | # endif |
359 | 350 | ||
360 | # ifdef HAVE_UNISTD_H | 351 | # include <unistd.h> |
361 | # include <unistd.h> | ||
362 | # endif | ||
363 | |||
364 | # include <stdio.h> | ||
365 | 352 | ||
366 | /* LOAD_AVE_TYPE should only get defined if we're going to use the | 353 | /* LOAD_AVE_TYPE should only get defined if we're going to use the |
367 | nlist method. */ | 354 | nlist method. */ |
@@ -435,7 +422,6 @@ extern int errno; | |||
435 | # endif /* sgi */ | 422 | # endif /* sgi */ |
436 | 423 | ||
437 | # ifdef UMAX | 424 | # ifdef UMAX |
438 | # include <stdio.h> | ||
439 | # include <signal.h> | 425 | # include <signal.h> |
440 | # include <sys/time.h> | 426 | # include <sys/time.h> |
441 | # include <sys/wait.h> | 427 | # include <sys/wait.h> |
@@ -461,17 +447,13 @@ extern int errno; | |||
461 | # include <sys/dg_sys_info.h> | 447 | # include <sys/dg_sys_info.h> |
462 | # endif | 448 | # endif |
463 | 449 | ||
464 | # if defined (HAVE_FCNTL_H) || defined (_POSIX_VERSION) | 450 | # include "fcntl--.h" |
465 | # include <fcntl.h> | ||
466 | # else | ||
467 | # include <sys/file.h> | ||
468 | # endif | ||
469 | 451 | ||
470 | /* Avoid static vars inside a function since in HPUX they dump as pure. */ | 452 | /* Avoid static vars inside a function since in HPUX they dump as pure. */ |
471 | 453 | ||
472 | # ifdef NeXT | 454 | # ifdef NeXT |
473 | static processor_set_t default_set; | 455 | static processor_set_t default_set; |
474 | static int getloadavg_initialized; | 456 | static bool getloadavg_initialized; |
475 | # endif /* NeXT */ | 457 | # endif /* NeXT */ |
476 | 458 | ||
477 | # ifdef UMAX | 459 | # ifdef UMAX |
@@ -486,8 +468,8 @@ static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */ | |||
486 | # if !defined (HAVE_LIBKSTAT) && defined (LOAD_AVE_TYPE) | 468 | # if !defined (HAVE_LIBKSTAT) && defined (LOAD_AVE_TYPE) |
487 | /* File descriptor open to /dev/kmem or VMS load ave driver. */ | 469 | /* File descriptor open to /dev/kmem or VMS load ave driver. */ |
488 | static int channel; | 470 | static int channel; |
489 | /* Nonzero iff channel is valid. */ | 471 | /* True iff channel is valid. */ |
490 | static int getloadavg_initialized; | 472 | static bool getloadavg_initialized; |
491 | /* Offset in kmem to seek to read load average, or 0 means invalid. */ | 473 | /* Offset in kmem to seek to read load average, or 0 means invalid. */ |
492 | static long offset; | 474 | static long offset; |
493 | 475 | ||
@@ -583,7 +565,7 @@ getloadavg (double loadavg[], int nelem) | |||
583 | 565 | ||
584 | # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ | 566 | # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ |
585 | 567 | ||
586 | # if !defined (LDAV_DONE) && defined (__linux__) | 568 | # if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__)) |
587 | # define LDAV_DONE | 569 | # define LDAV_DONE |
588 | # undef LOAD_AVE_TYPE | 570 | # undef LOAD_AVE_TYPE |
589 | 571 | ||
@@ -591,32 +573,36 @@ getloadavg (double loadavg[], int nelem) | |||
591 | # define LINUX_LDAV_FILE "/proc/loadavg" | 573 | # define LINUX_LDAV_FILE "/proc/loadavg" |
592 | # endif | 574 | # endif |
593 | 575 | ||
594 | char ldavgbuf[40]; | 576 | char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; |
595 | double load_ave[3]; | 577 | char const *ptr = ldavgbuf; |
596 | int fd, count; | 578 | int fd, count; |
597 | 579 | ||
598 | fd = open (LINUX_LDAV_FILE, O_RDONLY); | 580 | fd = open (LINUX_LDAV_FILE, O_RDONLY); |
599 | if (fd == -1) | 581 | if (fd == -1) |
600 | return -1; | 582 | return -1; |
601 | count = read (fd, ldavgbuf, 40); | 583 | count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); |
602 | (void) close (fd); | 584 | (void) close (fd); |
603 | if (count <= 0) | 585 | if (count <= 0) |
604 | return -1; | 586 | return -1; |
587 | ldavgbuf[count] = '\0'; | ||
605 | 588 | ||
606 | /* The following sscanf must use the C locale. */ | 589 | for (elem = 0; elem < nelem; elem++) |
607 | setlocale (LC_NUMERIC, "C"); | 590 | { |
608 | count = sscanf (ldavgbuf, "%lf %lf %lf", | 591 | char *endptr; |
609 | &load_ave[0], &load_ave[1], &load_ave[2]); | 592 | double d = c_strtod (ptr, &endptr); |
610 | setlocale (LC_NUMERIC, ""); | 593 | if (ptr == endptr) |
611 | if (count < 1) | 594 | { |
612 | return -1; | 595 | if (elem == 0) |
613 | 596 | return -1; | |
614 | for (elem = 0; elem < nelem && elem < count; elem++) | 597 | break; |
615 | loadavg[elem] = load_ave[elem]; | 598 | } |
599 | loadavg[elem] = d; | ||
600 | ptr = endptr; | ||
601 | } | ||
616 | 602 | ||
617 | return elem; | 603 | return elem; |
618 | 604 | ||
619 | # endif /* __linux__ */ | 605 | # endif /* __linux__ || __CYGWIN__ */ |
620 | 606 | ||
621 | # if !defined (LDAV_DONE) && defined (__NetBSD__) | 607 | # if !defined (LDAV_DONE) && defined (__NetBSD__) |
622 | # define LDAV_DONE | 608 | # define LDAV_DONE |
@@ -653,7 +639,7 @@ getloadavg (double loadavg[], int nelem) | |||
653 | 639 | ||
654 | host_t host; | 640 | host_t host; |
655 | struct processor_set_basic_info info; | 641 | struct processor_set_basic_info info; |
656 | unsigned info_count; | 642 | unsigned int info_count; |
657 | 643 | ||
658 | /* We only know how to get the 1-minute average for this system, | 644 | /* We only know how to get the 1-minute average for this system, |
659 | so even if the caller asks for more than 1, we only return 1. */ | 645 | so even if the caller asks for more than 1, we only return 1. */ |
@@ -661,7 +647,7 @@ getloadavg (double loadavg[], int nelem) | |||
661 | if (!getloadavg_initialized) | 647 | if (!getloadavg_initialized) |
662 | { | 648 | { |
663 | if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) | 649 | if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) |
664 | getloadavg_initialized = 1; | 650 | getloadavg_initialized = true; |
665 | } | 651 | } |
666 | 652 | ||
667 | if (getloadavg_initialized) | 653 | if (getloadavg_initialized) |
@@ -670,7 +656,7 @@ getloadavg (double loadavg[], int nelem) | |||
670 | if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, | 656 | if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, |
671 | (processor_set_info_t) &info, &info_count) | 657 | (processor_set_info_t) &info, &info_count) |
672 | != KERN_SUCCESS) | 658 | != KERN_SUCCESS) |
673 | getloadavg_initialized = 0; | 659 | getloadavg_initialized = false; |
674 | else | 660 | else |
675 | { | 661 | { |
676 | if (nelem > 0) | 662 | if (nelem > 0) |
@@ -831,7 +817,7 @@ getloadavg (double loadavg[], int nelem) | |||
831 | /* VMS specific code -- read from the Load Ave driver. */ | 817 | /* VMS specific code -- read from the Load Ave driver. */ |
832 | 818 | ||
833 | LOAD_AVE_TYPE load_ave[3]; | 819 | LOAD_AVE_TYPE load_ave[3]; |
834 | static int getloadavg_initialized = 0; | 820 | static bool getloadavg_initialized; |
835 | # ifdef eunice | 821 | # ifdef eunice |
836 | struct | 822 | struct |
837 | { | 823 | { |
@@ -851,7 +837,7 @@ getloadavg (double loadavg[], int nelem) | |||
851 | $DESCRIPTOR (descriptor, "LAV0:"); | 837 | $DESCRIPTOR (descriptor, "LAV0:"); |
852 | # endif | 838 | # endif |
853 | if (sys$assign (&descriptor, &channel, 0, 0) & 1) | 839 | if (sys$assign (&descriptor, &channel, 0, 0) & 1) |
854 | getloadavg_initialized = 1; | 840 | getloadavg_initialized = true; |
855 | } | 841 | } |
856 | 842 | ||
857 | /* Read the load average vector. */ | 843 | /* Read the load average vector. */ |
@@ -860,7 +846,7 @@ getloadavg (double loadavg[], int nelem) | |||
860 | load_ave, 12, 0, 0, 0, 0) & 1)) | 846 | load_ave, 12, 0, 0, 0, 0) & 1)) |
861 | { | 847 | { |
862 | sys$dassgn (channel); | 848 | sys$dassgn (channel); |
863 | getloadavg_initialized = 0; | 849 | getloadavg_initialized = false; |
864 | } | 850 | } |
865 | 851 | ||
866 | if (!getloadavg_initialized) | 852 | if (!getloadavg_initialized) |
@@ -913,7 +899,7 @@ getloadavg (double loadavg[], int nelem) | |||
913 | 899 | ||
914 | ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); | 900 | ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); |
915 | if (ldav_off != -1) | 901 | if (ldav_off != -1) |
916 | offset = (long) ldav_off & 0x7fffffff; | 902 | offset = (long int) ldav_off & 0x7fffffff; |
917 | # endif /* sgi */ | 903 | # endif /* sgi */ |
918 | } | 904 | } |
919 | 905 | ||
@@ -921,13 +907,13 @@ getloadavg (double loadavg[], int nelem) | |||
921 | if (!getloadavg_initialized) | 907 | if (!getloadavg_initialized) |
922 | { | 908 | { |
923 | # ifndef SUNOS_5 | 909 | # ifndef SUNOS_5 |
924 | channel = open ("/dev/kmem", 0); | 910 | channel = open ("/dev/kmem", O_RDONLY); |
925 | if (channel >= 0) | 911 | if (channel >= 0) |
926 | { | 912 | { |
927 | /* Set the channel to close on exec, so it does not | 913 | /* Set the channel to close on exec, so it does not |
928 | litter any child's descriptor table. */ | 914 | litter any child's descriptor table. */ |
929 | set_cloexec_flag (channel, true); | 915 | set_cloexec_flag (channel, true); |
930 | getloadavg_initialized = 1; | 916 | getloadavg_initialized = true; |
931 | } | 917 | } |
932 | # else /* SUNOS_5 */ | 918 | # else /* SUNOS_5 */ |
933 | /* We pass 0 for the kernel, corefile, and swapfile names | 919 | /* We pass 0 for the kernel, corefile, and swapfile names |
@@ -938,7 +924,7 @@ getloadavg (double loadavg[], int nelem) | |||
938 | /* nlist the currently running kernel. */ | 924 | /* nlist the currently running kernel. */ |
939 | kvm_nlist (kd, nl); | 925 | kvm_nlist (kd, nl); |
940 | offset = nl[0].n_value; | 926 | offset = nl[0].n_value; |
941 | getloadavg_initialized = 1; | 927 | getloadavg_initialized = true; |
942 | } | 928 | } |
943 | # endif /* SUNOS_5 */ | 929 | # endif /* SUNOS_5 */ |
944 | } | 930 | } |
@@ -953,14 +939,14 @@ getloadavg (double loadavg[], int nelem) | |||
953 | != sizeof (load_ave)) | 939 | != sizeof (load_ave)) |
954 | { | 940 | { |
955 | close (channel); | 941 | close (channel); |
956 | getloadavg_initialized = 0; | 942 | getloadavg_initialized = false; |
957 | } | 943 | } |
958 | # else /* SUNOS_5 */ | 944 | # else /* SUNOS_5 */ |
959 | if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) | 945 | if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) |
960 | != sizeof (load_ave)) | 946 | != sizeof (load_ave)) |
961 | { | 947 | { |
962 | kvm_close (kd); | 948 | kvm_close (kd); |
963 | getloadavg_initialized = 0; | 949 | getloadavg_initialized = false; |
964 | } | 950 | } |
965 | # endif /* SUNOS_5 */ | 951 | # endif /* SUNOS_5 */ |
966 | } | 952 | } |
@@ -980,20 +966,19 @@ getloadavg (double loadavg[], int nelem) | |||
980 | # define LDAV_DONE | 966 | # define LDAV_DONE |
981 | # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ | 967 | # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ |
982 | 968 | ||
983 | # ifdef LDAV_DONE | 969 | # if !defined LDAV_DONE |
984 | return elem; | ||
985 | # else | ||
986 | /* Set errno to zero to indicate that there was no particular error; | 970 | /* Set errno to zero to indicate that there was no particular error; |
987 | this function just can't work at all on this system. */ | 971 | this function just can't work at all on this system. */ |
988 | errno = 0; | 972 | errno = 0; |
989 | return -1; | 973 | elem = -1; |
990 | # endif | 974 | # endif |
975 | return elem; | ||
991 | } | 976 | } |
992 | 977 | ||
993 | #endif /* ! HAVE_GETLOADAVG */ | 978 | #endif /* ! HAVE_GETLOADAVG */ |
994 | 979 | ||
995 | #ifdef TEST | 980 | #ifdef TEST |
996 | void | 981 | int |
997 | main (int argc, char **argv) | 982 | main (int argc, char **argv) |
998 | { | 983 | { |
999 | int naptime = 0; | 984 | int naptime = 0; |
@@ -1011,7 +996,7 @@ main (int argc, char **argv) | |||
1011 | if (loads == -1) | 996 | if (loads == -1) |
1012 | { | 997 | { |
1013 | perror ("Error getting load average"); | 998 | perror ("Error getting load average"); |
1014 | exit (1); | 999 | return EXIT_FAILURE; |
1015 | } | 1000 | } |
1016 | if (loads > 0) | 1001 | if (loads > 0) |
1017 | printf ("1-minute: %f ", avg[0]); | 1002 | printf ("1-minute: %f ", avg[0]); |
@@ -1027,6 +1012,6 @@ main (int argc, char **argv) | |||
1027 | sleep (naptime); | 1012 | sleep (naptime); |
1028 | } | 1013 | } |
1029 | 1014 | ||
1030 | exit (0); | 1015 | return EXIT_SUCCESS; |
1031 | } | 1016 | } |
1032 | #endif /* TEST */ | 1017 | #endif /* TEST */ |