On Mon, Jul 06, 2009 at 03:22:56AM +0000, Paul Ackersviller wrote:
> On Thu, Jul 02, 2009 at 03:19:15PM -0700, Micah Cowan wrote:
> > Paul Ackersviller wrote:
> >
> > OTOH, screen appears to have seven different implementations for its
> > GetLoadav function; it's entirely possible the wrong one was chosen for
> > that build, or that the one that was chosen had some problems.
> 
> From what I see in loadav.c, the one used on the system in question is
> at the end, under the comment
>  * The old fashion way: open kernel and read avenrun
> Nothing there looks too unusual...
> 

I've figured out how to display the correct load averages by looking
at GNU's implementation of uptime.  I've created yet another GetLoadav
function implementing that method for HP-UX.  Because it makes use of
HP-UX's pstat_getdynamic() function, it has the nice benefit of not
directly reading the values from kernel memory, and thus does not need
to run setuid root.

I've also fixed a few more build problems while I was at it.  On the
HP-UX system I use at work, ./configure failed because it couldn't get
sockets or fifos to work.  The problem is that some functions used by
HP-UX's socket API is defined in sys/time.h instead of sys/select.h.
In fact, HP-UX doesn't even have sys/select.h.  Through a combination
of #ifdefs and #includes I was able to make it build.

Furthermore, HP-UX doesn't have a setenv() function, so I had to tweak
the configure script to use GNU screen's built-in implementation.

I've built and run this patch on a HP-UX 11.11 machine, a SunOS 5.10
as well as a couple of linux boxes.

I also have SunOS 5.10 and 5.9 servers, and AIX 6.1 and 5.3 servers
that I'm working on porting this latest release to.  I haven't yet
gotten them to a state where the full build completes, so look forward
to new patches in the coming days.

Micah, please let me know what I can do differently in the future to
make this code conform to your preferred coding standards.  I haven't
been able to find a document describing what is expected, and I'd like
my contributions to cause as few headaches as possible.

-- 
Erik Falor
Registered Linux User #445632 http://counter.li.org
diff --git a/src/acconfig.h b/src/acconfig.h
index bc324d5..a8d8986 100644
--- a/src/acconfig.h
+++ b/src/acconfig.h
@@ -31,6 +31,12 @@
  *     User Configuration Section
  */
 
+#ifdef hpux
+#define _XOPEN_SOURCE_EXTENDED
+#define __INCLUDE_FROM_TIME_H
+#endif
+
+
 /*
  * Maximum of simultaneously allowed windows per screen session.
  */
@@ -465,6 +471,15 @@
 #undef NLIST_NAME_UNION
 
 /*
+ * For HP-UX 9 and greater, the pstat_getdynamic() routine is the standard way
+ * to retrieve the system's load average.  This is the way the load average is
+ * reported by GNU uptime as well as the HP-UX provided uptime.
+ * pstat_getdynamic() has the further benefit of not requiring root privs to
+ * read directly from kernel memory.
+ */
+#undef HAVE_PSTAT_GETDYNAMIC
+
+/*
  * If your system has the new format /etc/ttys (like 4.3 BSD) and the
  * getttyent(3) library functions, define GETTTYENT.
  */
diff --git a/src/configure.in b/src/configure.in
index 9db3dd6..ab38bca 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -302,7 +302,11 @@ dnl
 AC_CHECKING(fifos)
 AC_TRY_RUN([
 /* For select - According to POSIX 1003.1-2001 */
+#ifndef hpux
 #include <sys/select.h>
+#else
+#include <sys/time.h>
+#endif
 
 /* For select - According to earlier standards */
 #include <sys/time.h>
@@ -372,7 +376,11 @@ if test -n "$fifo"; then
 AC_CHECKING(for broken fifo implementation)
 AC_TRY_RUN([
 /* For select - According to POSIX 1003.1-2001 */
+#ifndef hpux
 #include <sys/select.h>
+#else
+#include <sys/time.h>
+#endif
 
 /* For select - According to earlier standards */
 #include <sys/time.h>
@@ -426,7 +434,11 @@ dnl
 AC_CHECKING(sockets)
 AC_TRY_RUN([
 /* For select - According to POSIX 1003.1-2001 */
+#ifndef hpux
 #include <sys/select.h>
+#else
+#include <sys/time.h>
+#endif
 
 /* For select - According to earlier standards */
 #include <sys/time.h>
@@ -482,7 +494,11 @@ if test -n "$sock"; then
 AC_CHECKING(socket implementation)
 AC_TRY_RUN([
 /* For select - According to POSIX 1003.1-2001 */
+#ifndef hpux
 #include <sys/select.h>
+#else
+#include <sys/time.h>
+#endif
 
 /* For select - According to earlier standards */
 #include <sys/time.h>
@@ -549,7 +565,11 @@ dnl
 AC_CHECKING(select return value)
 AC_TRY_RUN([
 /* For select - According to POSIX 1003.1-2001 */
+#ifndef hpux
 #include <sys/select.h>
+#else
+#include <sys/time.h>
+#endif
 
 /* For select - According to earlier standards */
 #include <sys/time.h>
@@ -873,6 +893,23 @@ fi
 dnl
 dnl    ****  loadav  ****
 dnl
+
+dnl check for sys/pstat.h for HP-UX 9 and greater
+AC_CHECK_HEADER(sys/pstat.h, have_sys_pstat=yes, have_sys_pstat=no)
+if test "$have_sys_pstat" = yes; then
+AC_TRY_RUN([
+#include <sys/pstat.h>
+
+int main() {
+#ifdef hpux
+       struct pst_dynamic dyn_info;
+       pstat_getdynamic(&dyn_info, sizeof(dyn_info), 0, 0);
+       return 0;
+#endif
+}
+], AC_DEFINE(HAVE_PSTAT_GETDYNAMIC))
+fi
+
 AC_CHECKING(for libutil(s))
 test -f /usr/lib/libutils.a && LIBS="$LIBS -lutils"
 test -f /usr/lib/libutil.a && LIBS="$LIBS -lutil"
@@ -1211,14 +1248,14 @@ AC_HEADER_DIRENT
 
 AC_MSG_CHECKING(for setenv)
 if test -z "$ac_setenv_args"; then
-    AC_TRY_COMPILE(
+    AC_TRY_LINK(
     [#include <stdlib.h>],
     [
         setenv((char *) 0, (char *) 0, 0);
     ], ac_setenv_args=3)
 fi
 if test -z "$ac_setenv_args"; then
-    AC_TRY_COMPILE(
+    AC_TRY_LINK(
     [#include <stdlib.h>],
     [
         setenv((char *) 0, (char *) 0);
diff --git a/src/loadav.c b/src/loadav.c
index 770010c..5895ed5 100644
--- a/src/loadav.c
+++ b/src/loadav.c
@@ -42,6 +42,10 @@
 # endif
 #endif
 
+#ifdef hpux
+# include <sys/pstat.h>
+#endif
+
 #include "config.h"
 #include "screen.h"
 
@@ -151,6 +155,34 @@ GetLoadav()
 
 /***************************************************************/
 
+#if defined(hpux) && defined (HAVE_PSTAT_GETDYNAMIC) && !defined(LOADAV_DONE)
+#define LOADAV_DONE
+static struct pst_dynamic dyn_info;
+
+void
+InitLoadav()
+{
+  loadok = 1;
+}
+
+static int
+GetLoadav()
+{
+       if ( pstat_getdynamic(&dyn_info, sizeof(dyn_info), 0, 0) > -1 )
+       {
+               loadav[0] = dyn_info.psd_avg_1_min;
+               loadav[1] = dyn_info.psd_avg_5_min;
+               loadav[2] = dyn_info.psd_avg_15_min;
+               return LOADAV_NUM;
+       }
+       else
+       {
+               return 0;
+       }
+}
+
+#endif
+
 #if defined(NeXT) && !defined(LOADAV_DONE)
 #define LOADAV_DONE
 
diff --git a/src/os.h b/src/os.h
index b56b660..cf62010 100644
--- a/src/os.h
+++ b/src/os.h
@@ -488,7 +488,7 @@ extern int errno;
  *    select stuff
  */
 
-#if defined(M_XENIX) || defined(M_UNIX) || defined(_SEQUENT_)
+#if (defined(M_XENIX) || defined(M_UNIX) || defined(_SEQUENT_) ) && 
!defined(hpux)
 #include <sys/select.h>                /* for timeval + FD... */
 #endif
 

Reply via email to