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