]> code.delx.au - gnu-emacs/blobdiff - src/getloadavg.c
(set_properties, add_properties, remove_properties):
[gnu-emacs] / src / getloadavg.c
index 99521b757fa6db921c55d880f6591d7202a3aec9..2411e6a92254aee586f379a5ed57c8946107c9a9 100644 (file)
@@ -1,5 +1,5 @@
 /* Get the system load averages.
-   Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994
+   Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994, 1995
        Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -14,7 +14,8 @@
 
    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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+   USA.  */
 
 /* Compile-time symbols that this file uses:
 
 
    apollo
    BSD                         Real BSD, not just BSD-like.
+   convex
    DGUX
    eunice                      UNIX emulator under VMS.
    hpux
+   MSDOS                       No-op for MSDOS.
    NeXT
    sgi
    sequent                     Sequent Dynix 3.x.x (BSD)
@@ -49,6 +52,7 @@
    UMAX
    UMAX4_3
    VMS
+   WIN32                       No-op for Windows95/NT.
    __linux__                   Linux: assumes /proc filesystem mounted.
                                Support from Michael K. Johnson.
    __NetBSD__                  NetBSD: assumes /kern filesystem mounted.
    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
+#include <config.h>
+#endif
+
 #include <sys/types.h>
 
 /* Both the Emacs and non-Emacs sections want this.  Some
 #endif
 
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 /* Exclude all the code except the test program at the end
    if the system has its own `getloadavg' function.
 
@@ -136,7 +141,7 @@ extern int errno;
 #define decstation
 #endif
 
-#if defined(sun) && defined(SVR4)
+#if (defined(sun) && defined(SVR4)) || defined (SOLARIS2)
 #define SUNOS_5
 #endif
 
@@ -209,6 +214,17 @@ extern int errno;
 #define LOAD_AVE_TYPE long
 #endif
 
+#ifdef _AIX
+#define LOAD_AVE_TYPE long
+#endif
+
+#ifdef convex
+#define LOAD_AVE_TYPE double
+#ifndef LDAV_CVT
+#define LDAV_CVT(n) (n)
+#endif
+#endif
+
 #endif /* No LOAD_AVE_TYPE.  */
 
 #ifdef OSF_ALPHA
@@ -253,6 +269,10 @@ extern int errno;
 #define FSCALE 100.0
 #endif
 
+#ifdef _AIX
+#define FSCALE 65536.0
+#endif
+
 #endif /* Not FSCALE.  */
 
 #if !defined (LDAV_CVT) && defined (FSCALE)
@@ -314,6 +334,10 @@ extern int errno;
 #define NLIST_STRUCT
 #endif
 
+#ifdef _AIX
+#define NLIST_STRUCT
+#endif
+
 #endif /* defined (NLIST_STRUCT) */
 
 
@@ -339,7 +363,7 @@ extern int errno;
 #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)))
+#if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX))
 #define LDAV_SYMBOL "avenrun"
 #endif
 
@@ -367,6 +391,7 @@ extern int errno;
 #ifdef SUNOS_5
 #include <fcntl.h>
 #include <kvm.h>
+#include <kstat.h>
 #endif
 
 #ifndef KERNEL_FILE
@@ -492,6 +517,50 @@ getloadavg (loadavg, nelem)
   elem = -1;
 #endif
 
+#if !defined (LDAV_DONE) && defined (SUNOS_5)
+/* Use libkstat because we don't have to be root.  */
+#define LDAV_DONE
+  kstat_ctl_t *kc;
+  kstat_t *ksp;
+  kstat_named_t *kn;
+
+  kc = kstat_open ();
+  if (kc == 0) return -1;
+  ksp = kstat_lookup (kc, "unix", 0, "system_misc");
+  if (ksp == 0 ) return -1;
+  if (kstat_read (kc, ksp, 0) == -1) return -1;
+  
+
+  kn = kstat_data_lookup (ksp, "avenrun_1min");
+  if (kn == 0)
+    {
+      /* Return -1 if no load average information is available.  */
+      nelem = 0;
+      elem = -1;
+    }
+
+  if (nelem >= 1)
+    loadavg[elem++] = (double) kn->value.ul/FSCALE;
+
+  if (nelem >= 2)
+    {
+      kn = kstat_data_lookup (ksp, "avenrun_5min");
+      if (kn != 0)
+       {
+         loadavg[elem++] = (double) kn->value.ul/FSCALE;
+
+         if (nelem >= 3)
+           {
+             kn = kstat_data_lookup (ksp, "avenrun_15min");
+             if (kn != 0)
+               loadavg[elem++] = (double) kn->value.ul/FSCALE;
+           }
+       }
+    }
+
+  kstat_close (kc);
+#endif /* SUNOS_5 */
+
 #if !defined (LDAV_DONE) && defined (__linux__)
 #define LDAV_DONE
 #undef LOAD_AVE_TYPE
@@ -711,6 +780,16 @@ getloadavg (loadavg, nelem)
        : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
 #endif /* OSF_MIPS */
 
+#if !defined (LDAV_DONE) && (defined (MSDOS) || defined (WIN32))
+#define LDAV_DONE
+
+  /* A faithful emulation is going to have to be saved for a rainy day.  */
+  for ( ; elem < nelem; elem++)
+    {
+      loadavg[elem] = 0.0;
+    }
+#endif  /* MSDOS */
+
 #if !defined (LDAV_DONE) && defined (OSF_ALPHA)
 #define LDAV_DONE
 
@@ -789,23 +868,29 @@ getloadavg (loadavg, nelem)
 #endif /* NLIST_STRUCT */
 
 #ifndef SUNOS_5
-      if (nlist (KERNEL_FILE, nl) >= 0)
-       /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
-       {
+      if (
+#if !(defined (_AIX) && !defined (ps2))
+         nlist (KERNEL_FILE, nl)
+#else  /* _AIX */
+         knlist (nl, 1, sizeof (nl[0]))
+#endif
+         >= 0)
+         /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
+         {
 #ifdef FIXUP_KERNEL_SYMBOL_ADDR
-         FIXUP_KERNEL_SYMBOL_ADDR (nl);
+           FIXUP_KERNEL_SYMBOL_ADDR (nl);
 #endif
-         offset = nl[0].n_value;
-       }
-#endif  /* !SUNOS_5 */
-#else /* sgi */
-      int ldav_off;
+           offset = nl[0].n_value;
+         }
+#endif /* !SUNOS_5 */
+#else  /* sgi */
+         int ldav_off;
 
-      ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
-      if (ldav_off != -1)
-       offset = (long) ldav_off & 0x7fffffff;
+         ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
+         if (ldav_off != -1)
+         offset = (long) ldav_off & 0x7fffffff;
 #endif /* sgi */
-    }
+       }
 
   /* Make sure we have /dev/kmem open.  */
   if (!getloadavg_initialized)
@@ -813,12 +898,22 @@ getloadavg (loadavg, nelem)
 #ifndef SUNOS_5
       channel = open ("/dev/kmem", 0);
       if (channel >= 0)
-       getloadavg_initialized = 1;
+       {
+         /* Set the channel to close on exec, so it does not
+            litter any child's descriptor table.  */
+#ifdef FD_SETFD
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 1
+#endif
+         (void) fcntl (channel, F_SETFD, FD_CLOEXEC);
+#endif
+         getloadavg_initialized = 1;
+       }
 #else /* SUNOS_5 */
       /* We pass 0 for the kernel, corefile, and swapfile names
         to use the currently running kernel.  */
       kd = kvm_open (0, 0, 0, O_RDONLY, 0);
-      if (kd != 0) 
+      if (kd != 0)
        {
          /* nlist the currently running kernel.  */
          kvm_nlist (kd, nl);