diff options
Diffstat (limited to 'gl/getloadavg.c')
-rw-r--r-- | gl/getloadavg.c | 234 |
1 files changed, 104 insertions, 130 deletions
diff --git a/gl/getloadavg.c b/gl/getloadavg.c index c6d782b4..6e228191 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-2010 Free Software | 3 | Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2013 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. |
@@ -28,7 +28,7 @@ | |||
28 | macro that comes with autoconf 2.13 or newer. | 28 | macro that comes with autoconf 2.13 or newer. |
29 | If that isn't an option, then just put | 29 | If that isn't an option, then just put |
30 | AC_CHECK_FUNCS(pstat_getdynamic) in your | 30 | AC_CHECK_FUNCS(pstat_getdynamic) in your |
31 | configure.in file. | 31 | configure.ac file. |
32 | HAVE_LIBPERFSTAT Define this if your system has the | 32 | HAVE_LIBPERFSTAT Define this if your system has the |
33 | perfstat_cpu_total function in libperfstat (AIX). | 33 | perfstat_cpu_total function in libperfstat (AIX). |
34 | FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. | 34 | FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. |
@@ -46,7 +46,7 @@ | |||
46 | NLIST_STRUCT Include nlist.h, not a.out.h. | 46 | NLIST_STRUCT Include nlist.h, not a.out.h. |
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__, __CYGWIN__]: File containing |
51 | load averages. | 51 | load averages. |
52 | 52 | ||
@@ -80,52 +80,23 @@ | |||
80 | We also #define LDAV_PRIVILEGED if a program will require | 80 | We also #define LDAV_PRIVILEGED if a program will require |
81 | special installation to be able to call getloadavg. */ | 81 | special installation to be able to call getloadavg. */ |
82 | 82 | ||
83 | /* "configure" defines CONFIGURING_GETLOADAVG to sidestep problems | 83 | #include <config.h> |
84 | with partially-configured source directories. */ | ||
85 | |||
86 | #ifndef CONFIGURING_GETLOADAVG | ||
87 | # include <config.h> | ||
88 | # include <stdbool.h> | ||
89 | #endif | ||
90 | 84 | ||
91 | /* Specification. */ | 85 | /* Specification. */ |
92 | #include <stdlib.h> | 86 | #include <stdlib.h> |
93 | 87 | ||
94 | #include <errno.h> | 88 | #include <errno.h> |
89 | #include <stdbool.h> | ||
95 | #include <stdio.h> | 90 | #include <stdio.h> |
96 | 91 | ||
97 | /* Exclude all the code except the test program at the end | ||
98 | if the system has its own `getloadavg' function. */ | ||
99 | |||
100 | #ifndef HAVE_GETLOADAVG | ||
101 | |||
102 | # include <sys/types.h> | 92 | # include <sys/types.h> |
103 | 93 | ||
104 | /* Both the Emacs and non-Emacs sections want this. Some | 94 | # if HAVE_SYS_PARAM_H |
105 | configuration files' definitions for the LOAD_AVE_CVT macro (like | ||
106 | sparc.h's) use macros like FSCALE, defined here. */ | ||
107 | # if defined (unix) || defined (__unix) | ||
108 | # include <sys/param.h> | 95 | # include <sys/param.h> |
109 | # endif | 96 | # endif |
110 | 97 | ||
111 | # include "c-strtod.h" | ||
112 | # include "cloexec.h" | ||
113 | # include "intprops.h" | 98 | # include "intprops.h" |
114 | 99 | ||
115 | /* The existing Emacs configuration files define a macro called | ||
116 | LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and | ||
117 | returns the load average multiplied by 100. What we actually want | ||
118 | is a macro called LDAV_CVT, which returns the load average as an | ||
119 | unmultiplied double. | ||
120 | |||
121 | For backwards compatibility, we'll define LDAV_CVT in terms of | ||
122 | LOAD_AVE_CVT, but future machine config files should just define | ||
123 | LDAV_CVT directly. */ | ||
124 | |||
125 | # if !defined (LDAV_CVT) && defined (LOAD_AVE_CVT) | ||
126 | # define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0) | ||
127 | # endif | ||
128 | |||
129 | # if !defined (BSD) && defined (ultrix) | 100 | # if !defined (BSD) && defined (ultrix) |
130 | /* Ultrix behaves like BSD on Vaxen. */ | 101 | /* Ultrix behaves like BSD on Vaxen. */ |
131 | # define BSD | 102 | # define BSD |
@@ -372,7 +343,6 @@ | |||
372 | # endif /* NLIST_STRUCT */ | 343 | # endif /* NLIST_STRUCT */ |
373 | 344 | ||
374 | # ifdef SUNOS_5 | 345 | # ifdef SUNOS_5 |
375 | # include <fcntl.h> | ||
376 | # include <kvm.h> | 346 | # include <kvm.h> |
377 | # include <kstat.h> | 347 | # include <kstat.h> |
378 | # endif | 348 | # endif |
@@ -461,7 +431,10 @@ | |||
461 | # include <sys/dg_sys_info.h> | 431 | # include <sys/dg_sys_info.h> |
462 | # endif | 432 | # endif |
463 | 433 | ||
464 | # include "fcntl--.h" | 434 | # if (defined __linux__ || defined __CYGWIN__ || defined SUNOS_5 \ |
435 | || (defined LOAD_AVE_TYPE && ! defined __VMS)) | ||
436 | # include <fcntl.h> | ||
437 | # endif | ||
465 | 438 | ||
466 | /* Avoid static vars inside a function since in HPUX they dump as pure. */ | 439 | /* Avoid static vars inside a function since in HPUX they dump as pure. */ |
467 | 440 | ||
@@ -482,13 +455,13 @@ static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */ | |||
482 | # if !defined (HAVE_LIBKSTAT) && defined (LOAD_AVE_TYPE) | 455 | # if !defined (HAVE_LIBKSTAT) && defined (LOAD_AVE_TYPE) |
483 | /* File descriptor open to /dev/kmem or VMS load ave driver. */ | 456 | /* File descriptor open to /dev/kmem or VMS load ave driver. */ |
484 | static int channel; | 457 | static int channel; |
485 | /* True iff channel is valid. */ | 458 | /* True if channel is valid. */ |
486 | static bool getloadavg_initialized; | 459 | static bool getloadavg_initialized; |
487 | /* Offset in kmem to seek to read load average, or 0 means invalid. */ | 460 | /* Offset in kmem to seek to read load average, or 0 means invalid. */ |
488 | static long offset; | 461 | static long offset; |
489 | 462 | ||
490 | # if ! defined __VMS && ! defined sgi && ! defined __linux__ | 463 | # if ! defined __VMS && ! defined sgi && ! defined __linux__ |
491 | static struct nlist nl[2]; | 464 | static struct nlist name_list[2]; |
492 | # endif | 465 | # endif |
493 | 466 | ||
494 | # ifdef SUNOS_5 | 467 | # ifdef SUNOS_5 |
@@ -500,7 +473,7 @@ static kvm_t *kd; | |||
500 | /* Put the 1 minute, 5 minute and 15 minute load averages | 473 | /* Put the 1 minute, 5 minute and 15 minute load averages |
501 | into the first NELEM elements of LOADAVG. | 474 | into the first NELEM elements of LOADAVG. |
502 | Return the number written (never more than 3, but may be less than NELEM), | 475 | Return the number written (never more than 3, but may be less than NELEM), |
503 | or -1 if an error occurred. */ | 476 | or -1 (setting errno) if an error occurred. */ |
504 | 477 | ||
505 | int | 478 | int |
506 | getloadavg (double loadavg[], int nelem) | 479 | getloadavg (double loadavg[], int nelem) |
@@ -509,18 +482,17 @@ getloadavg (double loadavg[], int nelem) | |||
509 | 482 | ||
510 | # ifdef NO_GET_LOAD_AVG | 483 | # ifdef NO_GET_LOAD_AVG |
511 | # define LDAV_DONE | 484 | # define LDAV_DONE |
512 | /* Set errno to zero to indicate that there was no particular error; | 485 | errno = ENOSYS; |
513 | this function just can't work at all on this system. */ | ||
514 | errno = 0; | ||
515 | elem = -1; | 486 | elem = -1; |
516 | # endif | 487 | # endif |
517 | 488 | ||
518 | # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) | 489 | # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) /* Solaris <= 2.6 */ |
519 | /* Use libkstat because we don't have to be root. */ | 490 | /* Use libkstat because we don't have to be root. */ |
520 | # define LDAV_DONE | 491 | # define LDAV_DONE |
521 | kstat_ctl_t *kc; | 492 | kstat_ctl_t *kc; |
522 | kstat_t *ksp; | 493 | kstat_t *ksp; |
523 | kstat_named_t *kn; | 494 | kstat_named_t *kn; |
495 | int saved_errno; | ||
524 | 496 | ||
525 | kc = kstat_open (); | 497 | kc = kstat_open (); |
526 | if (kc == 0) | 498 | if (kc == 0) |
@@ -559,10 +531,13 @@ getloadavg (double loadavg[], int nelem) | |||
559 | } | 531 | } |
560 | } | 532 | } |
561 | 533 | ||
534 | saved_errno = errno; | ||
562 | kstat_close (kc); | 535 | kstat_close (kc); |
536 | errno = saved_errno; | ||
563 | # endif /* HAVE_LIBKSTAT */ | 537 | # endif /* HAVE_LIBKSTAT */ |
564 | 538 | ||
565 | # if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) | 539 | # if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) |
540 | /* HP-UX */ | ||
566 | /* Use pstat_getdynamic() because we don't have to be root. */ | 541 | /* Use pstat_getdynamic() because we don't have to be root. */ |
567 | # define LDAV_DONE | 542 | # define LDAV_DONE |
568 | # undef LOAD_AVE_TYPE | 543 | # undef LOAD_AVE_TYPE |
@@ -579,7 +554,7 @@ getloadavg (double loadavg[], int nelem) | |||
579 | 554 | ||
580 | # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ | 555 | # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ |
581 | 556 | ||
582 | # if ! defined LDAV_DONE && defined HAVE_LIBPERFSTAT | 557 | # if ! defined LDAV_DONE && defined HAVE_LIBPERFSTAT /* AIX */ |
583 | # define LDAV_DONE | 558 | # define LDAV_DONE |
584 | # undef LOAD_AVE_TYPE | 559 | # undef LOAD_AVE_TYPE |
585 | /* Use perfstat_cpu_total because we don't have to be root. */ | 560 | /* Use perfstat_cpu_total because we don't have to be root. */ |
@@ -596,6 +571,7 @@ getloadavg (double loadavg[], int nelem) | |||
596 | # endif | 571 | # endif |
597 | 572 | ||
598 | # if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__)) | 573 | # if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__)) |
574 | /* Linux without glibc, Cygwin */ | ||
599 | # define LDAV_DONE | 575 | # define LDAV_DONE |
600 | # undef LOAD_AVE_TYPE | 576 | # undef LOAD_AVE_TYPE |
601 | 577 | ||
@@ -605,39 +581,54 @@ getloadavg (double loadavg[], int nelem) | |||
605 | 581 | ||
606 | char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; | 582 | char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; |
607 | char const *ptr = ldavgbuf; | 583 | char const *ptr = ldavgbuf; |
608 | int fd, count; | 584 | int fd, count, saved_errno; |
609 | 585 | ||
610 | fd = open (LINUX_LDAV_FILE, O_RDONLY); | 586 | fd = open (LINUX_LDAV_FILE, O_RDONLY); |
611 | if (fd == -1) | 587 | if (fd == -1) |
612 | return -1; | 588 | return -1; |
613 | count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); | 589 | count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); |
590 | saved_errno = errno; | ||
614 | (void) close (fd); | 591 | (void) close (fd); |
592 | errno = saved_errno; | ||
615 | if (count <= 0) | 593 | if (count <= 0) |
616 | return -1; | 594 | return -1; |
617 | ldavgbuf[count] = '\0'; | 595 | ldavgbuf[count] = '\0'; |
618 | 596 | ||
619 | for (elem = 0; elem < nelem; elem++) | 597 | for (elem = 0; elem < nelem; elem++) |
620 | { | 598 | { |
621 | char *endptr; | 599 | double numerator = 0; |
622 | double d; | 600 | double denominator = 1; |
601 | |||
602 | while (*ptr == ' ') | ||
603 | ptr++; | ||
623 | 604 | ||
624 | errno = 0; | 605 | /* Finish if this number is missing, and report an error if all |
625 | d = c_strtod (ptr, &endptr); | 606 | were missing. */ |
626 | if (ptr == endptr || (d == 0 && errno != 0)) | 607 | if (! ('0' <= *ptr && *ptr <= '9')) |
627 | { | 608 | { |
628 | if (elem == 0) | 609 | if (elem == 0) |
629 | return -1; | 610 | { |
611 | errno = ENOTSUP; | ||
612 | return -1; | ||
613 | } | ||
630 | break; | 614 | break; |
631 | } | 615 | } |
632 | loadavg[elem] = d; | 616 | |
633 | ptr = endptr; | 617 | while ('0' <= *ptr && *ptr <= '9') |
618 | numerator = 10 * numerator + (*ptr++ - '0'); | ||
619 | |||
620 | if (*ptr == '.') | ||
621 | for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++) | ||
622 | numerator = 10 * numerator + (*ptr - '0'), denominator *= 10; | ||
623 | |||
624 | loadavg[elem++] = numerator / denominator; | ||
634 | } | 625 | } |
635 | 626 | ||
636 | return elem; | 627 | return elem; |
637 | 628 | ||
638 | # endif /* __linux__ || __CYGWIN__ */ | 629 | # endif /* __linux__ || __CYGWIN__ */ |
639 | 630 | ||
640 | # if !defined (LDAV_DONE) && defined (__NetBSD__) | 631 | # if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ |
641 | # define LDAV_DONE | 632 | # define LDAV_DONE |
642 | # undef LOAD_AVE_TYPE | 633 | # undef LOAD_AVE_TYPE |
643 | 634 | ||
@@ -657,7 +648,10 @@ getloadavg (double loadavg[], int nelem) | |||
657 | &scale); | 648 | &scale); |
658 | (void) fclose (fp); | 649 | (void) fclose (fp); |
659 | if (count != 4) | 650 | if (count != 4) |
660 | return -1; | 651 | { |
652 | errno = ENOTSUP; | ||
653 | return -1; | ||
654 | } | ||
661 | 655 | ||
662 | for (elem = 0; elem < nelem; elem++) | 656 | for (elem = 0; elem < nelem; elem++) |
663 | loadavg[elem] = (double) load_ave[elem] / (double) scale; | 657 | loadavg[elem] = (double) load_ave[elem] / (double) scale; |
@@ -666,7 +660,7 @@ getloadavg (double loadavg[], int nelem) | |||
666 | 660 | ||
667 | # endif /* __NetBSD__ */ | 661 | # endif /* __NetBSD__ */ |
668 | 662 | ||
669 | # if !defined (LDAV_DONE) && defined (NeXT) | 663 | # if !defined (LDAV_DONE) && defined (NeXT) /* NeXTStep */ |
670 | # define LDAV_DONE | 664 | # define LDAV_DONE |
671 | /* The NeXT code was adapted from iscreen 3.2. */ | 665 | /* The NeXT code was adapted from iscreen 3.2. */ |
672 | 666 | ||
@@ -698,7 +692,10 @@ getloadavg (double loadavg[], int nelem) | |||
698 | } | 692 | } |
699 | 693 | ||
700 | if (!getloadavg_initialized) | 694 | if (!getloadavg_initialized) |
701 | return -1; | 695 | { |
696 | errno = ENOTSUP; | ||
697 | return -1; | ||
698 | } | ||
702 | # endif /* NeXT */ | 699 | # endif /* NeXT */ |
703 | 700 | ||
704 | # if !defined (LDAV_DONE) && defined (UMAX) | 701 | # if !defined (LDAV_DONE) && defined (UMAX) |
@@ -732,7 +729,7 @@ getloadavg (double loadavg[], int nelem) | |||
732 | for (i = 0; i < conf.config_maxclass; ++i) | 729 | for (i = 0; i < conf.config_maxclass; ++i) |
733 | { | 730 | { |
734 | struct class_stats stats; | 731 | struct class_stats stats; |
735 | bzero ((char *) &stats, sizeof stats); | 732 | memset (&stats, 0, sizeof stats); |
736 | 733 | ||
737 | desc.sd_type = CPUTYPE_CLASS; | 734 | desc.sd_type = CPUTYPE_CLASS; |
738 | desc.sd_objid = i; | 735 | desc.sd_objid = i; |
@@ -775,7 +772,7 @@ getloadavg (double loadavg[], int nelem) | |||
775 | # define LDAV_DONE | 772 | # define LDAV_DONE |
776 | /* This call can return -1 for an error, but with good args | 773 | /* This call can return -1 for an error, but with good args |
777 | it's not supposed to fail. The first argument is for no | 774 | it's not supposed to fail. The first argument is for no |
778 | apparent reason of type `long int *'. */ | 775 | apparent reason of type 'long int *'. */ |
779 | dg_sys_info ((long int *) &load_info, | 776 | dg_sys_info ((long int *) &load_info, |
780 | DG_SYS_INFO_LOAD_INFO_TYPE, | 777 | DG_SYS_INFO_LOAD_INFO_TYPE, |
781 | DG_SYS_INFO_LOAD_VERSION_0); | 778 | DG_SYS_INFO_LOAD_VERSION_0); |
@@ -825,6 +822,7 @@ getloadavg (double loadavg[], int nelem) | |||
825 | # endif /* OSF_MIPS */ | 822 | # endif /* OSF_MIPS */ |
826 | 823 | ||
827 | # if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32)) | 824 | # if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32)) |
825 | /* DJGPP */ | ||
828 | # define LDAV_DONE | 826 | # define LDAV_DONE |
829 | 827 | ||
830 | /* A faithful emulation is going to have to be saved for a rainy day. */ | 828 | /* A faithful emulation is going to have to be saved for a rainy day. */ |
@@ -834,7 +832,7 @@ getloadavg (double loadavg[], int nelem) | |||
834 | } | 832 | } |
835 | # endif /* __MSDOS__ || WINDOWS32 */ | 833 | # endif /* __MSDOS__ || WINDOWS32 */ |
836 | 834 | ||
837 | # if !defined (LDAV_DONE) && defined (OSF_ALPHA) | 835 | # if !defined (LDAV_DONE) && defined (OSF_ALPHA) /* OSF/1 */ |
838 | # define LDAV_DONE | 836 | # define LDAV_DONE |
839 | 837 | ||
840 | struct tbl_loadavg load_ave; | 838 | struct tbl_loadavg load_ave; |
@@ -846,7 +844,7 @@ getloadavg (double loadavg[], int nelem) | |||
846 | : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); | 844 | : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); |
847 | # endif /* OSF_ALPHA */ | 845 | # endif /* OSF_ALPHA */ |
848 | 846 | ||
849 | # if ! defined LDAV_DONE && defined __VMS | 847 | # if ! defined LDAV_DONE && defined __VMS /* VMS */ |
850 | /* VMS specific code -- read from the Load Ave driver. */ | 848 | /* VMS specific code -- read from the Load Ave driver. */ |
851 | 849 | ||
852 | LOAD_AVE_TYPE load_ave[3]; | 850 | LOAD_AVE_TYPE load_ave[3]; |
@@ -883,10 +881,14 @@ getloadavg (double loadavg[], int nelem) | |||
883 | } | 881 | } |
884 | 882 | ||
885 | if (!getloadavg_initialized) | 883 | if (!getloadavg_initialized) |
886 | return -1; | 884 | { |
885 | errno = ENOTSUP; | ||
886 | return -1; | ||
887 | } | ||
887 | # endif /* ! defined LDAV_DONE && defined __VMS */ | 888 | # endif /* ! defined LDAV_DONE && defined __VMS */ |
888 | 889 | ||
889 | # if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS | 890 | # if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS |
891 | /* IRIX, other old systems */ | ||
890 | 892 | ||
891 | /* UNIX-specific code -- read the average from /dev/kmem. */ | 893 | /* UNIX-specific code -- read the average from /dev/kmem. */ |
892 | 894 | ||
@@ -899,38 +901,36 @@ getloadavg (double loadavg[], int nelem) | |||
899 | { | 901 | { |
900 | # ifndef sgi | 902 | # ifndef sgi |
901 | # if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER | 903 | # if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER |
902 | strcpy (nl[0].n_name, LDAV_SYMBOL); | 904 | strcpy (name_list[0].n_name, LDAV_SYMBOL); |
903 | strcpy (nl[1].n_name, ""); | 905 | strcpy (name_list[1].n_name, ""); |
904 | # else /* NLIST_STRUCT */ | 906 | # else /* NLIST_STRUCT */ |
905 | # ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME | 907 | # ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME |
906 | nl[0].n_un.n_name = LDAV_SYMBOL; | 908 | name_list[0].n_un.n_name = LDAV_SYMBOL; |
907 | nl[1].n_un.n_name = 0; | 909 | name_list[1].n_un.n_name = 0; |
908 | # else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ | 910 | # else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ |
909 | nl[0].n_name = LDAV_SYMBOL; | 911 | name_list[0].n_name = LDAV_SYMBOL; |
910 | nl[1].n_name = 0; | 912 | name_list[1].n_name = 0; |
911 | # endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ | 913 | # endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ |
912 | # endif /* NLIST_STRUCT */ | 914 | # endif /* NLIST_STRUCT */ |
913 | 915 | ||
914 | # ifndef SUNOS_5 | 916 | # ifndef SUNOS_5 |
915 | if ( | 917 | if ( |
916 | # if !(defined (_AIX) && !defined (ps2)) | 918 | # if !(defined (_AIX) && !defined (ps2)) |
917 | nlist (KERNEL_FILE, nl) | 919 | nlist (KERNEL_FILE, name_list) |
918 | # else /* _AIX */ | 920 | # else /* _AIX */ |
919 | knlist (nl, 1, sizeof (nl[0])) | 921 | knlist (name_list, 1, sizeof (name_list[0])) |
920 | # endif | 922 | # endif |
921 | >= 0) | 923 | >= 0) |
922 | /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */ | 924 | /* Omit "&& name_list[0].n_type != 0 " -- it breaks on Sun386i. */ |
923 | { | 925 | { |
924 | # ifdef FIXUP_KERNEL_SYMBOL_ADDR | 926 | # ifdef FIXUP_KERNEL_SYMBOL_ADDR |
925 | FIXUP_KERNEL_SYMBOL_ADDR (nl); | 927 | FIXUP_KERNEL_SYMBOL_ADDR (name_list); |
926 | # endif | 928 | # endif |
927 | offset = nl[0].n_value; | 929 | offset = name_list[0].n_value; |
928 | } | 930 | } |
929 | # endif /* !SUNOS_5 */ | 931 | # endif /* !SUNOS_5 */ |
930 | # else /* sgi */ | 932 | # else /* sgi */ |
931 | int ldav_off; | 933 | ptrdiff_t ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); |
932 | |||
933 | ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); | ||
934 | if (ldav_off != -1) | 934 | if (ldav_off != -1) |
935 | offset = (long int) ldav_off & 0x7fffffff; | 935 | offset = (long int) ldav_off & 0x7fffffff; |
936 | # endif /* sgi */ | 936 | # endif /* sgi */ |
@@ -940,13 +940,27 @@ getloadavg (double loadavg[], int nelem) | |||
940 | if (!getloadavg_initialized) | 940 | if (!getloadavg_initialized) |
941 | { | 941 | { |
942 | # ifndef SUNOS_5 | 942 | # ifndef SUNOS_5 |
943 | channel = open ("/dev/kmem", O_RDONLY); | 943 | /* Set the channel to close on exec, so it does not |
944 | if (channel >= 0) | 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); | ||
949 | if (0 <= fd) | ||
945 | { | 950 | { |
946 | /* Set the channel to close on exec, so it does not | 951 | # if F_DUPFD_CLOEXEC |
947 | litter any child's descriptor table. */ | 952 | if (fd <= STDERR_FILENO) |
948 | set_cloexec_flag (channel, true); | 953 | { |
949 | getloadavg_initialized = true; | 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 | } | ||
950 | } | 964 | } |
951 | # else /* SUNOS_5 */ | 965 | # else /* SUNOS_5 */ |
952 | /* We pass 0 for the kernel, corefile, and swapfile names | 966 | /* We pass 0 for the kernel, corefile, and swapfile names |
@@ -955,8 +969,8 @@ getloadavg (double loadavg[], int nelem) | |||
955 | if (kd != 0) | 969 | if (kd != 0) |
956 | { | 970 | { |
957 | /* nlist the currently running kernel. */ | 971 | /* nlist the currently running kernel. */ |
958 | kvm_nlist (kd, nl); | 972 | kvm_nlist (kd, name_list); |
959 | offset = nl[0].n_value; | 973 | offset = name_list[0].n_value; |
960 | getloadavg_initialized = true; | 974 | getloadavg_initialized = true; |
961 | } | 975 | } |
962 | # endif /* SUNOS_5 */ | 976 | # endif /* SUNOS_5 */ |
@@ -985,7 +999,10 @@ getloadavg (double loadavg[], int nelem) | |||
985 | } | 999 | } |
986 | 1000 | ||
987 | if (offset == 0 || !getloadavg_initialized) | 1001 | if (offset == 0 || !getloadavg_initialized) |
988 | return -1; | 1002 | { |
1003 | errno = ENOTSUP; | ||
1004 | return -1; | ||
1005 | } | ||
989 | # endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */ | 1006 | # endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */ |
990 | 1007 | ||
991 | # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ | 1008 | # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ |
@@ -1000,51 +1017,8 @@ getloadavg (double loadavg[], int nelem) | |||
1000 | # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ | 1017 | # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ |
1001 | 1018 | ||
1002 | # if !defined LDAV_DONE | 1019 | # if !defined LDAV_DONE |
1003 | /* Set errno to zero to indicate that there was no particular error; | 1020 | errno = ENOSYS; |
1004 | this function just can't work at all on this system. */ | ||
1005 | errno = 0; | ||
1006 | elem = -1; | 1021 | elem = -1; |
1007 | # endif | 1022 | # endif |
1008 | return elem; | 1023 | return elem; |
1009 | } | 1024 | } |
1010 | |||
1011 | #endif /* ! HAVE_GETLOADAVG */ | ||
1012 | |||
1013 | #ifdef TEST | ||
1014 | int | ||
1015 | main (int argc, char **argv) | ||
1016 | { | ||
1017 | int naptime = 0; | ||
1018 | |||
1019 | if (argc > 1) | ||
1020 | naptime = atoi (argv[1]); | ||
1021 | |||
1022 | while (1) | ||
1023 | { | ||
1024 | double avg[3]; | ||
1025 | int loads; | ||
1026 | |||
1027 | errno = 0; /* Don't be misled if it doesn't set errno. */ | ||
1028 | loads = getloadavg (avg, 3); | ||
1029 | if (loads == -1) | ||
1030 | { | ||
1031 | perror ("Error getting load average"); | ||
1032 | return EXIT_FAILURE; | ||
1033 | } | ||
1034 | if (loads > 0) | ||
1035 | printf ("1-minute: %f ", avg[0]); | ||
1036 | if (loads > 1) | ||
1037 | printf ("5-minute: %f ", avg[1]); | ||
1038 | if (loads > 2) | ||
1039 | printf ("15-minute: %f ", avg[2]); | ||
1040 | if (loads > 0) | ||
1041 | putchar ('\n'); | ||
1042 | |||
1043 | if (naptime == 0) | ||
1044 | break; | ||
1045 | sleep (naptime); | ||
1046 | } | ||
1047 | |||
1048 | return EXIT_SUCCESS; | ||
1049 | } | ||
1050 | #endif /* TEST */ | ||