summaryrefslogtreecommitdiffstats
path: root/gl/getloadavg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/getloadavg.c')
-rw-r--r--gl/getloadavg.c234
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. */
484static int channel; 457static int channel;
485/* True iff channel is valid. */ 458/* True if channel is valid. */
486static bool getloadavg_initialized; 459static 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. */
488static long offset; 461static long offset;
489 462
490# if ! defined __VMS && ! defined sgi && ! defined __linux__ 463# if ! defined __VMS && ! defined sgi && ! defined __linux__
491static struct nlist nl[2]; 464static 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
505int 478int
506getloadavg (double loadavg[], int nelem) 479getloadavg (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
1014int
1015main (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 */