X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fgetloadavg.c;h=a7bac490351185ca761954a30208be52a673c7e2;hb=d23630c01b90cbd1b713598f3c2c1b06400061b0;hp=b4b4e75178eb30a56c70cc400f5da3d9c8fdb6fd;hpb=8b03458ebe93a6e1c86c3a468aa3f2eee01e3c4c;p=gnulib.git diff --git a/lib/getloadavg.c b/lib/getloadavg.c index b4b4e7517..a7bac4903 100644 --- a/lib/getloadavg.c +++ b/lib/getloadavg.c @@ -1,15 +1,16 @@ /* Get the system load averages. Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, - 1995, 1997, 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + 1995, 1997, 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free + Software Foundation, Inc. NOTE: The canonical source of this file is maintained with gnulib. Bugs can be reported to bug-gnulib@gnu.org. - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,9 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ + along with this program. If not, see . */ /* Compile-time symbols that this file uses: @@ -31,8 +30,10 @@ If that isn't an option, then just put AC_CHECK_FUNCS(pstat_getdynamic) in your configure.in file. + HAVE_LIBPERFSTAT Define this if your system has the + perfstat_cpu_total function in libperfstat (AIX). FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. - KERNEL_FILE Pathname of the kernel to nlist. + KERNEL_FILE Name of the kernel file to nlist. LDAV_CVT() Scale the load average from the kernel. Returns a double. LDAV_SYMBOL Name of kernel symbol giving load average. @@ -43,11 +44,12 @@ otherwise, no load average is available. HAVE_NLIST_H nlist.h is available. NLIST_STRUCT defaults to this. - NLIST_STRUCT Include nlist.h, not a.out.h, and - the nlist n_name element is a pointer, + NLIST_STRUCT Include nlist.h, not a.out.h. + N_NAME_POINTER The nlist n_name element is a pointer, not an array. HAVE_STRUCT_NLIST_N_UN_N_NAME `n_un.n_name' is member of `struct nlist'. - LINUX_LDAV_FILE [__linux__]: File containing load averages. + LINUX_LDAV_FILE [__linux__, __CYGWIN__]: File containing + load averages. Specific system predefines this file uses, aside from setting default values if not emacs: @@ -70,6 +72,7 @@ WINDOWS32 No-op for Windows95/NT. __linux__ Linux: assumes /proc file system mounted. Support from Michael K. Johnson. + __CYGWIN__ Cygwin emulates linux /proc/loadavg. __NetBSD__ NetBSD: assumes /kern file system mounted. In addition, to avoid nesting many #ifdefs, we internally set @@ -78,15 +81,19 @@ We also #define LDAV_PRIVILEGED if a program will require special installation to be able to call getloadavg. */ -/* This should always be first. */ -#ifdef HAVE_CONFIG_H +/* "configure" defines CONFIGURING_GETLOADAVG to sidestep problems + with partially-configured source directories. */ + +#ifndef CONFIGURING_GETLOADAVG # include +# include #endif +/* Specification. */ +#include + #include -#include #include -#include /* Exclude all the code except the test program at the end if the system has its own `getloadavg' function. */ @@ -183,6 +190,8 @@ # include # include # include +/* Tru64 4.0D's table.h redefines sys */ +# undef sys # endif # if defined (__osf__) && (defined (mips) || defined (__mips__)) @@ -249,7 +258,7 @@ # define LOAD_AVE_TYPE long # endif -# ifdef _AIX +# if defined _AIX && ! defined HAVE_LIBPERFSTAT # define LOAD_AVE_TYPE long # endif @@ -277,7 +286,7 @@ # endif -# ifndef FSCALE +# ifndef FSCALE /* SunOS and some others define FSCALE in sys/param.h. */ @@ -304,7 +313,7 @@ # define FSCALE 100.0 # endif -# ifdef _AIX +# if defined _AIX && !defined HAVE_LIBPERFSTAT # define FSCALE 65536.0 # endif @@ -342,13 +351,11 @@ # define LDAV_SYMBOL "_Loadavg" # endif -# if !defined (LDAV_SYMBOL) && ((defined (hpux) && !defined (hp9000s300)) || defined (_SEQUENT_) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan)) || defined (_AIX)) +# if !defined (LDAV_SYMBOL) && ((defined (hpux) && !defined (hp9000s300)) || defined (_SEQUENT_) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan)) || (defined (_AIX) && !defined(HAVE_LIBPERFSTAT))) # define LDAV_SYMBOL "avenrun" # endif -# ifdef HAVE_UNISTD_H -# include -# endif +# include /* LOAD_AVE_TYPE should only get defined if we're going to use the nlist method. */ @@ -358,7 +365,7 @@ # ifdef LOAD_AVE_TYPE -# ifndef VMS +# ifndef __VMS # ifndef __linux__ # ifndef NLIST_STRUCT # include @@ -385,7 +392,7 @@ # endif /* LDAV_SYMBOL */ # endif /* __linux__ */ -# else /* VMS */ +# else /* __VMS */ # ifndef eunice # include @@ -393,7 +400,7 @@ # else /* eunice */ # include # endif /* eunice */ -# endif /* VMS */ +# endif /* __VMS */ # ifndef LDAV_CVT # define LDAV_CVT(n) ((double) (n)) @@ -401,6 +408,15 @@ # endif /* LOAD_AVE_TYPE */ +# if defined HAVE_LIBPERFSTAT +# include +# include +# include +# ifndef SBITS +# define SBITS 16 +# endif +# endif + # if defined (__GNU__) && !defined (NeXT) /* Note that NeXT Openstep defines __GNU__ even though it should not. */ /* GNU system acts much like NeXT, for load average purposes, @@ -447,13 +463,7 @@ # include # endif -# if defined (HAVE_FCNTL_H) || defined (_POSIX_VERSION) -# include -# else -# include -# endif - -# include "unistd-safer.h" +# include "fcntl--.h" /* Avoid static vars inside a function since in HPUX they dump as pure. */ @@ -479,9 +489,9 @@ static bool getloadavg_initialized; /* Offset in kmem to seek to read load average, or 0 means invalid. */ static long offset; -# if !defined (VMS) && !defined (sgi) && !defined (__linux__) +# if ! defined __VMS && ! defined sgi && ! defined __linux__ static struct nlist nl[2]; -# endif /* Not VMS or sgi */ +# endif # ifdef SUNOS_5 static kvm_t *kd; @@ -571,7 +581,23 @@ getloadavg (double loadavg[], int nelem) # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ -# if !defined (LDAV_DONE) && defined (__linux__) +# if ! defined LDAV_DONE && defined HAVE_LIBPERFSTAT +# define LDAV_DONE +# undef LOAD_AVE_TYPE +/* Use perfstat_cpu_total because we don't have to be root. */ + { + perfstat_cpu_total_t cpu_stats; + int result = perfstat_cpu_total (NULL, &cpu_stats, sizeof cpu_stats, 1); + if (result == -1) + return result; + loadavg[0] = cpu_stats.loadavg[0] / (double)(1 << SBITS); + loadavg[1] = cpu_stats.loadavg[1] / (double)(1 << SBITS); + loadavg[2] = cpu_stats.loadavg[2] / (double)(1 << SBITS); + elem = 3; + } +# endif + +# if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__)) # define LDAV_DONE # undef LOAD_AVE_TYPE @@ -579,7 +605,7 @@ getloadavg (double loadavg[], int nelem) # define LINUX_LDAV_FILE "/proc/loadavg" # endif - char ldavgbuf[3 * (INT_STRLEN_BOUND (long int) + sizeof ".00")]; + char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; char const *ptr = ldavgbuf; int fd, count; @@ -595,8 +621,11 @@ getloadavg (double loadavg[], int nelem) for (elem = 0; elem < nelem; elem++) { char *endptr; - double d = c_strtod (ptr, &endptr); - if (ptr == endptr) + double d; + + errno = 0; + d = c_strtod (ptr, &endptr); + if (ptr == endptr || (d == 0 && errno != 0)) { if (elem == 0) return -1; @@ -608,7 +637,7 @@ getloadavg (double loadavg[], int nelem) return elem; -# endif /* __linux__ */ +# endif /* __linux__ || __CYGWIN__ */ # if !defined (LDAV_DONE) && defined (__NetBSD__) # define LDAV_DONE @@ -819,7 +848,7 @@ getloadavg (double loadavg[], int nelem) : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); # endif /* OSF_ALPHA */ -# if !defined (LDAV_DONE) && defined (VMS) +# if ! defined LDAV_DONE && defined __VMS /* VMS specific code -- read from the Load Ave driver. */ LOAD_AVE_TYPE load_ave[3]; @@ -857,9 +886,9 @@ getloadavg (double loadavg[], int nelem) if (!getloadavg_initialized) return -1; -# endif /* VMS */ +# endif /* ! defined LDAV_DONE && defined __VMS */ -# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) && !defined (VMS) +# if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS /* UNIX-specific code -- read the average from /dev/kmem. */ @@ -871,7 +900,7 @@ getloadavg (double loadavg[], int nelem) if (offset == 0) { # ifndef sgi -# ifndef NLIST_STRUCT +# if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER strcpy (nl[0].n_name, LDAV_SYMBOL); strcpy (nl[1].n_name, ""); # else /* NLIST_STRUCT */ @@ -913,7 +942,7 @@ getloadavg (double loadavg[], int nelem) if (!getloadavg_initialized) { # ifndef SUNOS_5 - channel = fd_safer (open ("/dev/kmem", O_RDONLY)); + channel = open ("/dev/kmem", O_RDONLY); if (channel >= 0) { /* Set the channel to close on exec, so it does not @@ -959,7 +988,7 @@ getloadavg (double loadavg[], int nelem) if (offset == 0 || !getloadavg_initialized) return -1; -# endif /* LOAD_AVE_TYPE and not VMS */ +# endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */ # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ if (nelem > 0) @@ -972,14 +1001,13 @@ getloadavg (double loadavg[], int nelem) # define LDAV_DONE # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ -# ifdef LDAV_DONE - return elem; -# else +# if !defined LDAV_DONE /* Set errno to zero to indicate that there was no particular error; this function just can't work at all on this system. */ errno = 0; - return -1; + elem = -1; # endif + return elem; } #endif /* ! HAVE_GETLOADAVG */