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 */ | ||
