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