blob: 134b27f9d3929b8c1b9be9d7bf3d135fa038c96e [file] [log] [blame]
/* Portions of this file are subject to the following copyright(s). See
* the Net-SNMP's COPYING file for more details and other copyrights
* that may apply:
*/
/*
* Portions of this file are copyrighted by:
* Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms specified in the COPYING file
* distributed with the Net-SNMP package.
*/
/*
* Host Resources MIB - Running Software group implementation - hr_swrun.c
* (also includes Running Software Performance group )
*
*/
#include <net-snmp/net-snmp-config.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <fcntl.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/param.h>
#include <ctype.h>
#if HAVE_SYS_PSTAT_H
#include <sys/pstat.h>
#endif
#if HAVE_SYS_USER_H
#ifdef solaris2
#include <libgen.h>
#define _KMEMUSER
#endif
#include <sys/user.h>
#endif
#if HAVE_SYS_PROC_H
#include <sys/proc.h>
#endif
#if HAVE_KVM_H
#include <kvm.h>
#endif
#if HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#if HAVE_DIRENT_H && !defined(cygwin)
#include <dirent.h>
#else
# define dirent direct
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# if HAVE_NDIR_H
# include <ndir.h>
# endif
#endif
#ifdef cygwin
#include <windows.h>
#include <sys/cygwin.h>
#include <tlhelp32.h>
#include <psapi.h>
#endif
#if _SLASH_PROC_METHOD_
#include <procfs.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <stdio.h>
#include <net-snmp/output_api.h>
#include "host_res.h"
#include "hr_swrun.h"
#include <net-snmp/agent/auto_nlist.h>
#include "kernel.h"
#ifdef solaris2
#if _SLASH_PROC_METHOD_ && defined _ILP32
#include <net-snmp/agent/cache_handler.h>
#include <net-snmp/agent/hardware/memory.h>
#endif
#include "kernel_sunos5.h"
#endif
#if defined(aix4) || defined(aix5) || defined(aix6)
#include <procinfo.h>
#include <sys/types.h>
#endif
/*********************
*
* Initialisation & common implementation functions
*
*********************/
void Init_HR_SWRun(void);
int Get_Next_HR_SWRun(void);
void End_HR_SWRun(void);
int header_hrswrun(struct variable *, oid *, size_t *, int,
size_t *, WriteMethod **);
int header_hrswrunEntry(struct variable *, oid *, size_t *,
int, size_t *, WriteMethod **);
#ifdef dynix
pid_t nextproc;
static prpsinfo_t lowpsinfo, mypsinfo;
#endif
#ifdef cygwin
static struct external_pinfo *curproc;
static struct external_pinfo lowproc;
#elif !defined(linux)
static int LowProcIndex;
#endif
#if defined(hpux10) || defined(hpux11)
struct pst_status *proc_table;
struct pst_dynamic pst_dyn;
#elif HAVE_KVM_GETPROCS
struct kinfo_proc *proc_table;
#elif defined(solaris2)
int *proc_table;
#elif defined(aix4) || defined(aix5) || defined(aix6)
struct procsinfo *proc_table;
#else
struct proc *proc_table;
#endif
#ifndef dynix
int current_proc_entry;
#endif
#define HRSWRUN_OSINDEX 1
#define HRSWRUN_INDEX 2
#define HRSWRUN_NAME 3
#define HRSWRUN_ID 4
#define HRSWRUN_PATH 5
#define HRSWRUN_PARAMS 6
#define HRSWRUN_TYPE 7
#define HRSWRUN_STATUS 8
#define HRSWRUNPERF_CPU 9
#define HRSWRUNPERF_MEM 10
struct variable4 hrswrun_variables[] = {
{HRSWRUN_OSINDEX, ASN_INTEGER, RONLY, var_hrswrun, 1, {1}},
{HRSWRUN_INDEX, ASN_INTEGER, RONLY, var_hrswrun, 3, {2, 1, 1}},
{HRSWRUN_NAME, ASN_OCTET_STR, RONLY, var_hrswrun, 3, {2, 1, 2}},
{HRSWRUN_ID, ASN_OBJECT_ID, RONLY, var_hrswrun, 3, {2, 1, 3}},
{HRSWRUN_PATH, ASN_OCTET_STR, RONLY, var_hrswrun, 3, {2, 1, 4}},
{HRSWRUN_PARAMS, ASN_OCTET_STR, RONLY, var_hrswrun, 3, {2, 1, 5}},
{HRSWRUN_TYPE, ASN_INTEGER, RONLY, var_hrswrun, 3, {2, 1, 6}},
{HRSWRUN_STATUS, ASN_INTEGER, RONLY, var_hrswrun, 3, {2, 1, 7}}
};
struct variable4 hrswrunperf_variables[] = {
{HRSWRUNPERF_CPU, ASN_INTEGER, RONLY, var_hrswrun, 3, {1, 1, 1}},
{HRSWRUNPERF_MEM, ASN_INTEGER, RONLY, var_hrswrun, 3, {1, 1, 2}}
};
oid hrswrun_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 4 };
oid hrswrunperf_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 5 };
#ifdef cygwin
/*
* a lot of this is "stolen" from cygwin ps.cc
*/
typedef BOOL(WINAPI * ENUMPROCESSMODULES) (HANDLE hProcess,
HMODULE * lphModule,
DWORD cb,
LPDWORD lpcbNeeded);
typedef DWORD(WINAPI * GETMODULEFILENAME) (HANDLE hProcess,
HMODULE hModule,
LPTSTR lpstrFIleName,
DWORD nSize);
typedef DWORD(WINAPI * GETPROCESSMEMORYINFO) (HANDLE hProcess,
PPROCESS_MEMORY_COUNTERS
pmc, DWORD nSize);
typedef HANDLE(WINAPI * CREATESNAPSHOT) (DWORD dwFlags,
DWORD th32ProcessID);
typedef BOOL(WINAPI * PROCESSWALK) (HANDLE hSnapshot,
LPPROCESSENTRY32 lppe);
ENUMPROCESSMODULES myEnumProcessModules;
GETMODULEFILENAME myGetModuleFileNameEx;
CREATESNAPSHOT myCreateToolhelp32Snapshot;
PROCESSWALK myProcess32First;
PROCESSWALK myProcess32Next;
GETPROCESSMEMORYINFO myGetProcessMemoryInfo = NULL;
cygwin_getinfo_types query = CW_GETPINFO;
static BOOL WINAPI
dummyprocessmodules(HANDLE hProcess,
HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded)
{
lphModule[0] = (HMODULE) * lpcbNeeded;
*lpcbNeeded = 1;
return 1;
}
static DWORD WINAPI
GetModuleFileNameEx95(HANDLE hProcess,
HMODULE hModule, LPTSTR lpstrFileName, DWORD n)
{
HANDLE h;
DWORD pid = (DWORD) hModule;
PROCESSENTRY32 proc;
h = myCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (!h)
return 0;
proc.dwSize = sizeof(proc);
if (myProcess32First(h, &proc))
do
if (proc.th32ProcessID == pid) {
CloseHandle(h);
strcpy(lpstrFileName, proc.szExeFile);
return 1;
}
while (myProcess32Next(h, &proc));
CloseHandle(h);
return 0;
}
#define FACTOR (0x19db1ded53ea710LL)
#define NSPERSEC 10000000LL
#define NSPERMSEC 10000LL
static time_t __stdcall
to_time_t(PFILETIME ptr)
{
long rem;
long long x =
((long long) ptr->dwHighDateTime << 32) +
((unsigned) ptr->dwLowDateTime);
x -= FACTOR;
rem = x % NSPERSEC;
rem += NSPERSEC / 2;
x /= NSPERSEC;
x += rem / NSPERSEC;
return x;
}
static long
to_msec(PFILETIME ptr)
{
long long x =
((long long) ptr->dwHighDateTime << 32) +
(unsigned) ptr->dwLowDateTime;
x /= NSPERMSEC;
return x;
}
#endif /* cygwin */
void
init_hr_swrun(void)
{
#ifdef cygwin
OSVERSIONINFO ver;
HMODULE h;
memset(&ver, 0, sizeof ver);
ver.dwOSVersionInfoSize = sizeof ver;
GetVersionEx(&ver);
if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
h = LoadLibrary("psapi.dll");
if (h) {
myEnumProcessModules =
(ENUMPROCESSMODULES) GetProcAddress(h,
"EnumProcessModules");
myGetModuleFileNameEx =
(GETMODULEFILENAME) GetProcAddress(h,
"GetModuleFileNameExA");
myGetProcessMemoryInfo =
(GETPROCESSMEMORYINFO) GetProcAddress(h,
"GetProcessMemoryInfo");
if (myEnumProcessModules && myGetModuleFileNameEx)
query = CW_GETPINFO_FULL;
else
snmp_log(LOG_ERR, "hr_swrun failed NT init\n");
} else
snmp_log(LOG_ERR, "hr_swrun failed to load psapi.dll\n");
} else {
h = GetModuleHandle("KERNEL32.DLL");
myCreateToolhelp32Snapshot =
(CREATESNAPSHOT) GetProcAddress(h, "CreateToolhelp32Snapshot");
myProcess32First =
(PROCESSWALK) GetProcAddress(h, "Process32First");
myProcess32Next = (PROCESSWALK) GetProcAddress(h, "Process32Next");
myEnumProcessModules = dummyprocessmodules;
myGetModuleFileNameEx = GetModuleFileNameEx95;
if (myCreateToolhelp32Snapshot && myProcess32First
&& myProcess32Next)
#if 0
/*
* This doesn't work after all on Win98 SE
*/
query = CW_GETPINFO_FULL;
#else
query = CW_GETPINFO;
#endif
else
snmp_log(LOG_ERR, "hr_swrun failed non-NT init\n");
}
#endif /* cygwin */
#ifdef PROC_SYMBOL
auto_nlist(PROC_SYMBOL, 0, 0);
#endif
#ifdef NPROC_SYMBOL
auto_nlist(NPROC_SYMBOL, 0, 0);
#endif
proc_table = 0;
REGISTER_MIB("host/hr_swrun", hrswrun_variables, variable4,
hrswrun_variables_oid);
REGISTER_MIB("host/hr_swrun", hrswrunperf_variables, variable4,
hrswrunperf_variables_oid);
}
/*
* header_hrswrun(...
* Arguments:
* vp IN - pointer to variable entry that points here
* name IN/OUT - IN/name requested, OUT/name found
* length IN/OUT - length of IN/OUT oid's
* exact IN - TRUE if an exact match was requested
* var_len OUT - length of variable or 0 if function returned
* write_method
*
*/
int
header_hrswrun(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len, WriteMethod ** write_method)
{
#define HRSWRUN_NAME_LENGTH 9
oid newname[MAX_OID_LEN];
int result;
DEBUGMSGTL(("host/hr_swrun", "var_hrswrun: "));
DEBUGMSGOID(("host/hr_swrun", name, *length));
DEBUGMSG(("host/hr_swrun", " %d\n", exact));
memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
newname[HRSWRUN_NAME_LENGTH] = 0;
result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
if ((exact && (result != 0)) || (!exact && (result >= 0)))
return (MATCH_FAILED);
memcpy((char *) name, (char *) newname,
(vp->namelen + 1) * sizeof(oid));
*length = vp->namelen + 1;
*write_method = 0;
*var_len = sizeof(long); /* default to 'long' results */
return (MATCH_SUCCEEDED);
}
int
header_hrswrunEntry(struct variable *vp,
oid * name,
size_t * length,
int exact,
size_t * var_len, WriteMethod ** write_method)
{
#define HRSWRUN_ENTRY_NAME_LENGTH 11
oid newname[MAX_OID_LEN];
int pid, LowPid = -1;
int result;
DEBUGMSGTL(("host/hr_swrun", "var_hrswrunEntry: "));
DEBUGMSGOID(("host/hr_swrun", name, *length));
DEBUGMSG(("host/hr_swrun", " %d\n", exact));
memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
/*
* Find the "next" running process
*/
Init_HR_SWRun();
for (;;) {
pid = Get_Next_HR_SWRun();
#ifndef linux
#ifndef dynix
DEBUGMSG(("host/hr_swrun",
"(index %d (entry #%d) ....", pid, current_proc_entry));
#else
DEBUGMSG(("host/hr_swrun", "pid %d; nextproc %d ....", pid,
nextproc));
#endif
#endif
if (pid == -1)
break;
newname[HRSWRUN_ENTRY_NAME_LENGTH] = pid;
DEBUGMSGOID(("host/hr_swrun", newname, *length));
DEBUGMSG(("host/hr_swrun", "\n"));
result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
if (exact && (result == 0)) {
LowPid = pid;
#ifdef cygwin
lowproc = *curproc;
#elif dynix
memcpy(&lowpsinfo, &mypsinfo, sizeof(prpsinfo_t));
#elif !defined(linux)
LowProcIndex = current_proc_entry - 1;
#endif
DEBUGMSGTL(("host/hr_swrun", " saved\n"));
/*
* Save process status information
*/
break;
}
if ((!exact && (result < 0)) && (LowPid == -1 || pid < LowPid)) {
LowPid = pid;
#ifdef cygwin
lowproc = *curproc;
#elif !defined(linux)
LowProcIndex = current_proc_entry - 1;
#endif
/*
* Save process status information
*/
DEBUGMSG(("host/hr_swrun", " saved"));
}
DEBUGMSG(("host/hr_swrun", "\n"));
}
End_HR_SWRun();
if (LowPid == -1) {
DEBUGMSGTL(("host/hr_swrun", "... index out of range\n"));
return (MATCH_FAILED);
}
newname[HRSWRUN_ENTRY_NAME_LENGTH] = LowPid;
memcpy((char *) name, (char *) newname,
(vp->namelen + 1) * sizeof(oid));
*length = vp->namelen + 1;
*write_method = 0;
*var_len = sizeof(long); /* default to 'long' results */
DEBUGMSGTL(("host/hr_swrun", "... get process stats "));
DEBUGMSGOID(("host/hr_swrun", name, *length));
DEBUGMSG(("host/hr_swrun", "\n"));
return LowPid;
}
/*********************
*
* System specific implementation functions
*
*********************/
#if defined(linux)
static char *
skip_to_next_field(char *cp)
{
while (*cp && ! isspace(*cp)) /* skip past non-space */
++cp;
while (*cp && isspace(*cp)) /* skip past space */
++cp;
return cp;
}
static char *
get_proc_file_line(char *fmt,
int pid,
char *buf,
int buflen )
{
static char string[1024];
FILE *fp;
*buf = '\0';
sprintf(string,fmt,pid);
if ( ((fp = fopen(string, "r")) == NULL)
|| (fgets(buf, buflen, fp) == NULL) ) {
if (fp)
fclose(fp);
return NULL;
}
fclose(fp);
return buf;
}
static char *
get_proc_stat_field(int pid,
char *buf,
int buflen,
int skip )
{
int i;
char *cp;
if ((cp = get_proc_file_line("/proc/%d/stat", pid, buf, buflen)) == NULL )
return NULL;
for (i = 0; *cp && i < skip; ++i) {
cp = skip_to_next_field(cp);
}
return cp;
}
static char *
get_proc_name_from_cmdline(int pid,
char *buf,
int buflen )
{
return get_proc_file_line("/proc/%d/cmdline", pid, buf, buflen);
}
static char *
get_proc_name_from_status(int pid,
char *buf,
int buflen )
{
char *cp,*cp2;
if ((cp = get_proc_file_line("/proc/%d/status", pid, buf, buflen)) == NULL )
return NULL;
cp = strchr(cp, ':');
if ( cp == NULL ) {
return NULL; /* the process file is malformed */
}
cp = skip_to_next_field(cp);
cp2 = strchr(cp, '\n');
if (cp2)
*cp2 = 0;
return cp;
}
#endif
u_char *
var_hrswrun(struct variable * vp,
oid * name,
size_t * length,
int exact, size_t * var_len, WriteMethod ** write_method)
{
int pid = 0;
static char string[1024];
#ifdef HAVE_SYS_PSTAT_H
struct pst_status proc_buf;
#elif defined(solaris2)
#if _SLASH_PROC_METHOD_
static psinfo_t psinfo;
static psinfo_t *proc_buf;
int procfd;
int ret;
char procfn[sizeof "/proc/00000/psinfo"];
#else
static struct proc *proc_buf;
char *cp1;
#endif /* _SLASH_PROC_METHOD_ */
static time_t when = 0;
time_t now;
static int oldpid = -1;
#endif
#if HAVE_KVM_GETPROCS
char **argv;
#endif
#ifdef linux
FILE *fp;
char buf[1024];
int i;
#endif
char *cp;
if (vp->magic == HRSWRUN_OSINDEX) {
if (header_hrswrun(vp, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
} else {
pid =
header_hrswrunEntry(vp, name, length, exact, var_len,
write_method);
if (pid == MATCH_FAILED)
return NULL;
}
#ifdef HAVE_SYS_PSTAT_H
if (pstat_getproc(&proc_buf, sizeof(struct pst_status), 0, pid) == -1)
return NULL;
#elif defined(solaris2)
time(&now);
if (pid == oldpid) {
if (now != when)
oldpid = -1;
}
if (oldpid != pid || proc_buf == NULL) {
#if _SLASH_PROC_METHOD_
proc_buf = &psinfo;
sprintf(procfn, "/proc/%.5d/psinfo", pid);
if ((procfd = open(procfn, O_RDONLY)) != -1) {
ret = read(procfd, proc_buf, sizeof(*proc_buf));
close(procfd);
if (ret != sizeof(*proc_buf))
proc_buf = NULL;
} else
proc_buf = NULL;
#else
if (kd == NULL)
return NULL;
if ((proc_buf = kvm_getproc(kd, pid)) == NULL)
return NULL;
#endif
oldpid = pid;
when = now;
}
#endif
switch (vp->magic) {
case HRSWRUN_OSINDEX:
#if NETSNMP_NO_DUMMY_VALUES
return NULL;
#else
/*
* per dts, on coders:
* cos (in general) we won't know which process should
* be regarded as "the primary O/S process".
* The most obvious candidate on a Unix box is probably 'init'
* which is typically (always?) process #1.
*/
long_return = 1; /* Probably! */
return (u_char *) & long_return;
#endif
case HRSWRUN_INDEX:
long_return = pid;
return (u_char *) & long_return;
case HRSWRUN_NAME:
#ifdef HAVE_SYS_PSTAT_H
strlcpy(string, proc_buf.pst_cmd, sizeof(string));
cp = strchr(string, ' ');
if (cp != NULL)
*cp = '\0';
#elif defined(dynix)
strlcpy(string, lowpsinfo.pr_fname, sizeof(string));
cp = strchr(string, ' ');
if (cp != NULL)
*cp = '\0';
#elif defined(solaris2)
#if _SLASH_PROC_METHOD_
if (proc_buf) {
char *pos=strchr(proc_buf->pr_psargs,' ');
if (pos != NULL) *pos = '\0';
strlcpy(string, basename(proc_buf->pr_psargs), sizeof(string));
if (pos != NULL) *pos=' ';
} else {
strlcpy(string, "<exited>", sizeof(string));
}
#else
strlcpy(string, proc_buf->p_user.u_comm, sizeof(string));
#endif
#elif defined(aix4) || defined(aix5) || defined(aix6)
strlcpy(string, proc_table[LowProcIndex].pi_comm, sizeof(string));
cp = strchr(string, ' ');
if (cp != NULL)
*cp = '\0';
#elif HAVE_KVM_GETPROCS
#if defined(freebsd5) && __FreeBSD_version >= 500014
strcpy(string, proc_table[LowProcIndex].ki_comm);
#elif defined(dragonfly) && __DragonFly_version >= 190000
strcpy(string, proc_table[LowProcIndex].kp_comm);
#elif defined(openbsd5)
strcpy(string, proc_table[LowProcIndex].p_comm);
#else
strcpy(string, proc_table[LowProcIndex].kp_proc.p_comm);
#endif
#elif defined(linux)
if( (cp=get_proc_name_from_status(pid,buf,sizeof(buf))) == NULL ) {
strcpy(string, "<exited>");
*var_len = strlen(string);
return (u_char *) string;
}
strcpy(string, cp);
#elif defined(cygwin)
/* if (lowproc.process_state & (PID_ZOMBIE | PID_EXITED)) */
if (lowproc.process_state & PID_EXITED || (lowproc.exitcode & ~0xffff))
strcpy(string, "<defunct>");
else if (lowproc.ppid) {
cygwin_conv_to_posix_path(lowproc.progname, string);
cp = strrchr(string, '/');
if (cp)
strcpy(string, cp + 1);
} else if (query == CW_GETPINFO_FULL) {
DWORD n = lowproc.dwProcessId & 0xffff;
HANDLE h =
OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, n);
if (h) {
HMODULE hm[1000];
if (!myEnumProcessModules(h, hm, sizeof hm, &n)) {
snmp_log(LOG_DEBUG, "no module handle for %lu\n", n);
n = 0;
}
if (n
&& myGetModuleFileNameEx(h, hm[0], string,
sizeof string)) {
cp = strrchr(string, '\\');
if (cp)
strcpy(string, cp + 1);
} else
strcpy(string, "*** unknown");
CloseHandle(h);
} else {
snmp_log(LOG_INFO, "no process handle for %lu\n", n);
strcpy(string, "** unknown");
}
} else
strcpy(string, "* unknown");
cp = strchr(string, '\0') - 4;
if (cp > string && strcasecmp(cp, ".exe") == 0)
*cp = '\0';
#else
#if NETSNMP_NO_DUMMY_VALUES
return NULL;
#endif
sprintf(string, "process name");
#endif
*var_len = strlen(string);
/*
* remove trailing newline
*/
if (*var_len) {
cp = string + *var_len - 1;
if (*cp == '\n')
--(*var_len);
}
if (*var_len > 64) { /* MIB limit */
*var_len = 64;
string[64] = '\0';
}
return (u_char *) string;
case HRSWRUN_ID:
*var_len = nullOidLen;
return (u_char *) nullOid;
case HRSWRUN_PATH:
#ifdef HAVE_SYS_PSTAT_H
/*
* Path not available - use argv[0]
*/
sprintf(string, "%s", proc_buf.pst_cmd);
cp = strchr(string, ' ');
if (cp != NULL)
*cp = '\0';
#elif defined(dynix)
/*
* Path not available - use argv[0]
*/
sprintf(string, "%s", lowpsinfo.pr_psargs);
cp = strchr(string, ' ');
if (cp != NULL)
*cp = '\0';
#elif defined(solaris2)
#ifdef _SLASH_PROC_METHOD_
if (proc_buf)
strcpy(string, proc_buf->pr_psargs);
else
sprintf(string, "<exited>");
cp = strchr(string, ' ');
if (cp)
*cp = 0;
#else
cp = proc_buf->p_user.u_psargs;
cp1 = string;
while (*cp && *cp != ' ')
*cp1++ = *cp++;
*cp1 = 0;
#endif
#elif defined(aix4) || defined(aix5) || defined(aix6)
strlcpy(string, proc_table[LowProcIndex].pi_comm, sizeof(string));
cp = strchr(string, ' ');
if (cp != NULL)
*cp = '\0';
#elif HAVE_KVM_GETPROCS
#if defined(freebsd5) && __FreeBSD_version >= 500014
strcpy(string, proc_table[LowProcIndex].ki_comm);
#elif defined(dragonfly) && __DragonFly_version >= 190000
strcpy(string, proc_table[LowProcIndex].kp_comm);
#elif defined(openbsd5)
strcpy(string, proc_table[LowProcIndex].p_comm);
#else
strcpy(string, proc_table[LowProcIndex].kp_proc.p_comm);
#endif
#elif defined(linux)
cp = get_proc_name_from_cmdline(pid,buf,sizeof(buf)-1);
if (cp != NULL && *cp) /* argv[0] '\0' argv[1] '\0' .... */
strcpy(string, cp);
else {
/*
* swapped out - no cmdline
*/
if( (cp=get_proc_name_from_status(pid,buf,sizeof(buf)-1)) == NULL ) {
strcpy(string, "<exited>");
*var_len = strlen(string);
return (u_char *) string;
}
strcpy(string, cp);
}
#elif defined(cygwin)
/* if (lowproc.process_state & (PID_ZOMBIE | PID_EXITED)) */
if (lowproc.process_state & PID_EXITED || (lowproc.exitcode & ~0xffff))
strcpy(string, "<defunct>");
else if (lowproc.ppid)
cygwin_conv_to_posix_path(lowproc.progname, string);
else if (query == CW_GETPINFO_FULL) {
DWORD n = lowproc.dwProcessId & 0xFFFF;
HANDLE h =
OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, n);
if (h) {
HMODULE hm[1000];
if (!myEnumProcessModules(h, hm, sizeof hm, &n))
n = 0;
if (!n
|| !myGetModuleFileNameEx(h, hm[0], string,
sizeof string))
strcpy(string, "*** unknown");
CloseHandle(h);
} else
strcpy(string, "** unknown");
} else
strcpy(string, "* unknown");
#else
#if NETSNMP_NO_DUMMY_VALUES
return NULL;
#endif
sprintf(string, "/bin/wombat");
#endif
*var_len = strlen(string);
if (*var_len > 128) { /* MIB limit */
*var_len = 128;
string[128] = '\0';
}
return (u_char *) string;
case HRSWRUN_PARAMS:
#ifdef HAVE_SYS_PSTAT_H
cp = strchr(proc_buf.pst_cmd, ' ');
if (cp != NULL) {
cp++;
sprintf(string, "%s", cp);
} else
string[0] = '\0';
#elif defined(dynix)
cp = strchr(lowpsinfo.pr_psargs, ' ');
if (cp != NULL) {
cp++;
sprintf(string, "%s", cp);
} else
string[0] = '\0';
#elif defined(solaris2)
#ifdef _SLASH_PROC_METHOD_
if (proc_buf) {
cp = strchr(proc_buf->pr_psargs, ' ');
if (cp)
strcpy(string, cp + 1);
else
string[0] = 0;
} else
string[0] = 0;
#else
cp = proc_buf->p_user.u_psargs;
while (*cp && *cp != ' ')
cp++;
if (*cp == ' ')
cp++;
strcpy(string, cp);
#endif
#elif defined(aix4) || defined(aix5) || defined(aix6)
cp = strchr(proc_table[LowProcIndex].pi_comm, ' ');
if (cp != NULL) {
cp++;
sprintf(string, "%s", cp);
} else
string[0] = '\0';
#elif HAVE_KVM_GETPROCS
string[0] = 0;
argv = kvm_getargv(kd, proc_table + LowProcIndex, sizeof(string));
if (argv)
argv++;
while (argv && *argv) {
if (string[0] != 0)
strcat(string, " ");
strcat(string, *argv);
argv++;
}
#elif defined(linux)
memset(buf, 0, sizeof(buf));
if( (cp=get_proc_name_from_cmdline(pid,buf,sizeof(buf)-2)) == NULL ) {
strcpy(string, "");
*var_len = 0;
return (u_char *) string;
}
/*
* Skip over argv[0]
*/
cp = buf;
while (*cp)
++cp;
++cp;
/*
* Now join together separate arguments.
*/
while (1) {
while (*cp)
++cp;
if (*(cp + 1) == '\0')
break; /* '\0''\0' => End of command line */
*cp = ' ';
}
cp = buf;
while (*cp)
++cp;
++cp;
strcpy(string, cp);
#elif defined(cygwin)
string[0] = 0;
#else
#if NETSNMP_NO_DUMMY_VALUES
return NULL;
#endif
sprintf(string, "-h -q -v");
#endif
*var_len = strlen(string);
if (*var_len > 128) { /* MIB limit */
*var_len = 128;
string[128] = '\0';
}
return (u_char *) string;
case HRSWRUN_TYPE:
#ifdef PID_MAXSYS
if (pid < PID_MAXSYS)
long_return = 2; /* operatingSystem */
else
long_return = 4; /* application */
#elif defined(aix4) || defined(aix5) || defined(aix6)
if (proc_table[LowProcIndex].pi_flags & SKPROC) {
long_return = 2; /* kernel process */
} else
long_return = 4; /* application */
#elif HAVE_KVM_GETPROCS
#if defined(freebsd5) && __FreeBSD_version >= 500014
if (proc_table[LowProcIndex].ki_flag & P_SYSTEM) {
if (proc_table[LowProcIndex].ki_pri.pri_class == PRI_ITHD)
long_return = 3;/* deviceDriver */
else
long_return = 2;/* operatingSystem */
} else
long_return = 4; /* application */
#elif defined(openbsd5)
if (proc_table[LowProcIndex].p_flag & P_SYSTEM)
long_return = 2; /* operatingSystem */
else
long_return = 4; /* application */
#else
#if defined(dragonfly) && __DragonFly_version >= 190000
if (proc_table[LowProcIndex].kp_flags & P_SYSTEM)
#else
if (proc_table[LowProcIndex].kp_proc.p_flag & P_SYSTEM)
#endif
long_return = 2; /* operatingSystem */
else
long_return = 4; /* application */
#endif
#else
long_return = 4; /* application */
#endif
return (u_char *) & long_return;
case HRSWRUN_STATUS:
#if defined(cygwin)
if (lowproc.process_state & PID_STOPPED)
long_return = 3; /* notRunnable */
/* else if (lowproc.process_state & PID_ZOMBIE) */
else if (lowproc.exitcode & ~0xffff)
long_return = 4; /* invalid */
else
long_return = 1; /* running */
#elif !defined(linux)
#if defined(hpux10) || defined(hpux11)
switch (proc_table[LowProcIndex].pst_stat) {
case PS_STOP:
long_return = 3; /* notRunnable */
break;
case PS_SLEEP:
long_return = 2; /* runnable */
break;
case PS_RUN:
long_return = 1; /* running */
break;
case PS_ZOMBIE:
case PS_IDLE:
case PS_OTHER:
default:
long_return = 4; /* invalid */
break;
}
#else
#if HAVE_KVM_GETPROCS
#if defined(freebsd5) && __FreeBSD_version >= 500014
switch (proc_table[LowProcIndex].ki_stat) {
#elif defined(dragonfly) && __DragonFly_version >= 190000
switch (proc_table[LowProcIndex].kp_stat) {
#elif defined(openbsd5)
switch (proc_table[LowProcIndex].p_stat) {
#else
switch (proc_table[LowProcIndex].kp_proc.p_stat) {
#endif
#elif defined(dynix)
switch (lowpsinfo.pr_state) {
#elif defined(solaris2)
#if _SLASH_PROC_METHOD_
switch (proc_buf ? proc_buf->pr_lwp.pr_state : SIDL) {
#else
switch (proc_buf->p_stat) {
#endif
#elif defined(aix4) || defined(aix5) || defined(aix6)
switch (proc_table[LowProcIndex].pi_state) {
#else
switch (proc_table[LowProcIndex].p_stat) {
#endif
case SSTOP:
long_return = 3; /* notRunnable */
break;
case 0:
#ifdef SSWAP
case SSWAP:
#endif
#ifdef SSLEEP
case SSLEEP:
#endif
#ifdef SWAIT
case SWAIT:
#endif
long_return = 2; /* runnable */
break;
#ifdef SACTIVE
case SACTIVE:
#endif
#ifdef SRUN
case SRUN:
#endif
#ifdef SONPROC
case SONPROC:
#endif
long_return = 1; /* running */
break;
case SIDL:
case SZOMB:
default:
long_return = 4; /* invalid */
break;
}
#endif
#else
if ((cp = get_proc_stat_field(pid,buf,sizeof(buf),2)) != NULL ) {
switch (*cp) {
case 'R':
long_return = 1; /* running */
break;
case 'S':
long_return = 2; /* runnable */
break;
case 'D':
case 'T':
long_return = 3; /* notRunnable */
break;
case 'Z':
default:
long_return = 4; /* invalid */
break;
}
} else
long_return = 4; /* invalid */
#endif
return (u_char *) & long_return;
case HRSWRUNPERF_CPU:
#ifdef HAVE_SYS_PSTAT_H
long_return = proc_buf.pst_cptickstotal;
/*
* Not convinced this is right, but....
*/
#elif defined(dynix)
long_return = lowpsinfo.pr_time.tv_sec * 100 +
lowpsinfo.pr_time.tv_nsec / 10000000;
#elif defined(solaris2)
#if _SLASH_PROC_METHOD_
long_return = proc_buf ? proc_buf->pr_time.tv_sec * 100 +
proc_buf->pr_time.tv_nsec / 10000000 : 0;
#else
long_return = proc_buf->p_utime * 100 + proc_buf->p_stime * 100;
#endif
#elif HAVE_KVM_GETPROCS
#if defined(NOT_DEFINED) && defined(freebsd5) && __FreeBSD_version >= 500014
/* XXX: Accessing ki_paddr causes sig10 ...
long_return = proc_table[LowProcIndex].ki_paddr->p_uticks +
proc_table[LowProcIndex].ki_paddr->p_sticks +
proc_table[LowProcIndex].ki_paddr->p_iticks; */
long_return = 0;
#elif defined(freebsd5)
long_return = proc_table[LowProcIndex].ki_runtime / 100000;
#elif defined(dragonfly) && __DragonFly_version >= 190000
long_return = proc_table[LowProcIndex].kp_lwp.kl_uticks +
proc_table[LowProcIndex].kp_lwp.kl_sticks +
proc_table[LowProcIndex].kp_lwp.kl_iticks;
#elif defined(openbsd5)
long_return = proc_table[LowProcIndex].p_uticks +
proc_table[LowProcIndex].p_sticks +
proc_table[LowProcIndex].p_iticks;
#elif defined(dragonfly)
long_return = proc_table[LowProcIndex].kp_eproc.e_uticks +
proc_table[LowProcIndex].kp_eproc.e_sticks +
proc_table[LowProcIndex].kp_eproc.e_iticks;
#else
long_return = proc_table[LowProcIndex].kp_proc.p_uticks +
proc_table[LowProcIndex].kp_proc.p_sticks +
proc_table[LowProcIndex].kp_proc.p_iticks;
#endif
#elif defined(linux)
if ((cp = get_proc_stat_field(pid,buf,sizeof(buf),13)) == NULL ) {
long_return = 0;
return (u_char *) & long_return;
}
long_return = atoi(cp); /* utime */
cp = skip_to_next_field(cp);
long_return += atoi(cp); /* + stime */
#elif defined(sunos4)
long_return = proc_table[LowProcIndex].p_time;
#elif defined(cygwin)
{
DWORD n = lowproc.dwProcessId;
HANDLE h =
OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, n);
FILETIME ct, et, kt, ut;
if (h) {
if (GetProcessTimes(h, &ct, &et, &kt, &ut))
long_return = (to_msec(&kt) + to_msec(&ut)) / 10;
else {
snmp_log(LOG_INFO, "no process times for %lu (%lu)\n",
lowproc.pid, n);
long_return = 0;
}
CloseHandle(h);
} else {
snmp_log(LOG_INFO, "no process handle for %lu (%lu)\n",
lowproc.pid, n);
long_return = 0;
}
}
#elif defined(aix4) || defined(aix5) || defined(aix6)
long_return = proc_table[LowProcIndex].pi_ru.ru_utime.tv_sec * 100 +
proc_table[LowProcIndex].pi_ru.ru_utime.tv_usec / 10000000 + /* nanoseconds */
proc_table[LowProcIndex].pi_ru.ru_stime.tv_sec * 100 +
proc_table[LowProcIndex].pi_ru.ru_stime.tv_usec / 10000000; /* nanoseconds */
#else
long_return = proc_table[LowProcIndex].p_utime.tv_sec * 100 +
proc_table[LowProcIndex].p_utime.tv_usec / 10000 +
proc_table[LowProcIndex].p_stime.tv_sec * 100 +
proc_table[LowProcIndex].p_stime.tv_usec / 10000;
#endif
return (u_char *) & long_return;
case HRSWRUNPERF_MEM:
#ifdef HAVE_SYS_PSTAT_H
# ifdef PGSHIFT
long_return = (proc_buf.pst_rssize << PGSHIFT) / 1024;
# else
long_return = proc_buf.pst_rssize * getpagesize() / 1024;
# endif
#elif defined(dynix)
long_return = (lowpsinfo.pr_rssize * MMU_PAGESIZE) / 1024;
#elif defined(solaris2)
#if _SLASH_PROC_METHOD_
#ifdef _ILP32
if(NULL != proc_buf && 0 == proc_buf->pr_rssize)
{ /* Odds on that we are looking with a 32 bit app at a 64 bit psinfo.*/
netsnmp_memory_info *mem;
netsnmp_memory_load();
mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 0 );
if (!mem)
{
snmp_log(LOG_INFO, "netsnmp_memory_get_byIdx returned NULL pointer\n");
long_return = 0;/* Tried my best, giving up.*/
}
else
{/* 0x8000 is the maximum range of pr_pctmem. devision of 1024 is to go from B to kB*/
uint32_t pct_unit = (mem->size/0x8000) * (mem->units/1024);
long_return = proc_buf ? proc_buf->pr_pctmem * pct_unit : 0;
}
}
else
{
long_return = proc_buf ? proc_buf->pr_rssize : 0;
}
#else /*_LP64*/
long_return = proc_buf ? proc_buf->pr_rssize : 0;
#endif /*_LP64*/
#else
long_return = proc_buf->p_swrss;
#endif
#elif defined(aix4) || defined(aix5) || defined(aix6)
long_return = proc_table[LowProcIndex].pi_size * getpagesize() / 1024;
#elif HAVE_KVM_GETPROCS && !defined(darwin8)
#if defined(NOT_DEFINED) && defined(freebsd5) && __FreeBSD_version >= 500014
/* XXX
long_return = proc_table[LowProcIndex].ki_vmspace->vm_tsize +
proc_table[LowProcIndex].ki_vmspace->vm_ssize +
proc_table[LowProcIndex].ki_vmspace->vm_dsize;
long_return = long_return * (getpagesize() / 1024); */
long_return = 0;
#elif defined(freebsd3) && !defined(darwin)
long_return =
#if defined(freebsd5)
proc_table[LowProcIndex].ki_size / 1024;
#elif defined(dragonfly) && __DragonFly_version >= 190000
proc_table[LowProcIndex].kp_vm_map_size / 1024;
#else
proc_table[LowProcIndex].kp_eproc.e_vm.vm_map.size / 1024;
#endif
#elif defined(openbsd5)
long_return = proc_table[LowProcIndex].p_vm_tsize +
proc_table[LowProcIndex].p_vm_ssize +
proc_table[LowProcIndex].p_vm_dsize;
long_return = long_return * (getpagesize() / 1024);
#else
long_return = proc_table[LowProcIndex].kp_eproc.e_vm.vm_tsize +
proc_table[LowProcIndex].kp_eproc.e_vm.vm_ssize +
proc_table[LowProcIndex].kp_eproc.e_vm.vm_dsize;
long_return = long_return * (getpagesize() / 1024);
#endif
#elif defined(linux)
if ((cp = get_proc_stat_field(pid,buf,sizeof(buf),23)) == NULL ) {
long_return = 0;
return (u_char *) & long_return;
}
long_return = atoi(cp) * (getpagesize() / 1024); /* rss */
#elif defined(cygwin)
{
DWORD n = lowproc.dwProcessId;
HANDLE h =
OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, n);
PROCESS_MEMORY_COUNTERS pmc;
if (h) {
if (myGetProcessMemoryInfo
&& myGetProcessMemoryInfo(h, &pmc, sizeof pmc))
long_return = pmc.WorkingSetSize / 1024;
else {
snmp_log(LOG_INFO, "no process times for %lu (%lu)\n",
lowproc.pid, n);
long_return = 0;
}
CloseHandle(h);
} else {
snmp_log(LOG_INFO, "no process handle for %lu (%lu)\n",
lowproc.pid, n);
long_return = 0;
}
}
#else
#if NETSNMP_NO_DUMMY_VALUES
return NULL;
#endif
long_return = 16 * 1024; /* XXX - 16M! */
#endif
return (u_char *) & long_return;
default:
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrswrun\n",
vp->magic));
}
return NULL;
}
/*********************
*
* Internal implementation functions
*
*********************/
#if defined(linux)
DIR *procdir = NULL;
struct dirent *procentry_p;
void
Init_HR_SWRun(void)
{
if (procdir != NULL)
closedir(procdir);
procdir = opendir("/proc");
}
int
Get_Next_HR_SWRun(void)
{
int pid;
if (procdir == NULL)
return -1;
procentry_p = readdir(procdir);
if (procentry_p == NULL)
return -1;
pid = atoi(procentry_p->d_name);
if (pid == 0)
return (Get_Next_HR_SWRun());
return pid;
}
void
End_HR_SWRun(void)
{
if (procdir)
closedir(procdir);
procdir = NULL;
}
#elif defined(cygwin)
static pid_t curpid;
void
Init_HR_SWRun(void)
{
cygwin_internal(CW_LOCK_PINFO, 1000);
curpid = 0;
}
int
Get_Next_HR_SWRun(void)
{
curproc =
(struct external_pinfo *) cygwin_internal(query,
curpid | CW_NEXTPID);
if (curproc)
curpid = curproc->pid;
else {
curpid = -1;
}
return curpid;
}
void
End_HR_SWRun(void)
{
cygwin_internal(CW_UNLOCK_PINFO);
}
#elif defined(dynix)
void
Init_HR_SWRun(void)
{
nextproc = 0;
}
int
Get_Next_HR_SWRun(void)
{
getprpsinfo_t *select = 0;
DEBUGMSGTL(("host/hr_swrun::GetNextHR_SWRun",
"nextproc == %d... &nextproc = %u\n", nextproc,
&nextproc));
if ((nextproc = getprpsinfo(nextproc, select, &mypsinfo)) < 0) {
return -1;
} else {
DEBUGMSGTL(("host/hr_swrun::GetNextHR_SWRun",
"getprpsinfo returned %d\n", nextproc));
return mypsinfo.pr_pid;
}
}
void
End_HR_SWRun(void)
{
/*
* just a stub... because it's declared
*/
}
#else /* linux */
static int nproc;
void
Init_HR_SWRun(void)
{
size_t bytes;
static time_t iwhen = 0;
time_t now;
time(&now);
if (now == iwhen) {
current_proc_entry = 0;
return;
}
iwhen = now;
#if defined(hpux10) || defined(hpux11)
pstat_getdynamic(&pst_dyn, sizeof(struct pst_dynamic), 1, 0);
nproc = pst_dyn.psd_activeprocs;
bytes = nproc * sizeof(struct pst_status);
if ((proc_table =
(struct pst_status *) realloc(proc_table, bytes)) == NULL) {
current_proc_entry = nproc + 1;
return;
}
pstat_getproc(proc_table, sizeof(struct pst_status), nproc, 0);
#elif defined(solaris2)
if (getKstatInt("unix", "system_misc", "nproc", &nproc)) {
current_proc_entry = nproc + 1;
return;
}
bytes = nproc * sizeof(int);
if ((proc_table = (int *) realloc(proc_table, bytes)) == NULL) {
current_proc_entry = nproc + 1;
return;
}
{
DIR *f;
struct dirent *dp;
#if _SLASH_PROC_METHOD_ == 0
if (kd == NULL) {
current_proc_entry = nproc + 1;
return;
}
#endif
f = opendir("/proc");
current_proc_entry = 0;
while ((dp = readdir(f)) != NULL && current_proc_entry < nproc)
if (dp->d_name[0] != '.')
proc_table[current_proc_entry++] = atoi(dp->d_name);
/*
* if we are in a Solaris zone, nproc > current_proc_entry !
* but we only want the processes from the local zone
*/
if (current_proc_entry != nproc)
nproc = current_proc_entry;
closedir(f);
}
#elif defined(aix4) || defined(aix5) || defined(aix6)
{
pid_t proc_index = 0;
int avail = 1024;
if (proc_table) {
free(proc_table);
}
nproc = 0;
proc_table = malloc(sizeof(proc_table[0]) * avail);
for (;;) {
int got;
if (!proc_table) {
nproc = 0;
snmp_log_perror("Init_HR_SWRun-malloc");
return;
}
got = getprocs(proc_table + nproc, sizeof(proc_table[0]),
0, sizeof(struct fdsinfo),
&proc_index, avail - nproc);
nproc += got;
if (nproc < avail) {
break;
}
avail += 1024;
proc_table = realloc(proc_table, avail * sizeof(proc_table[0]));
}
}
#elif HAVE_KVM_GETPROCS
{
if (kd == NULL) {
nproc = 0;
return;
}
#if defined(openbsd5)
proc_table = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof (struct kinfo_proc), &nproc);
#else
proc_table = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc);
#endif
}
#else
current_proc_entry = 1;
#ifndef bsdi2
nproc = 0;
if (auto_nlist(NPROC_SYMBOL, (char *) &nproc, sizeof(int)) == 0) {
snmp_log_perror("Init_HR_SWRun-auto_nlist NPROC");
return;
}
#endif
bytes = nproc * sizeof(struct proc);
if (proc_table)
free((char *) proc_table);
if ((proc_table = (struct proc *) malloc(bytes)) == NULL) {
nproc = 0;
snmp_log_perror("Init_HR_SWRun-malloc");
return;
}
{
int proc_table_base;
if (auto_nlist
(PROC_SYMBOL, (char *) &proc_table_base,
sizeof(proc_table_base)) == 0) {
nproc = 0;
snmp_log_perror("Init_HR_SWRun-auto_nlist PROC");
return;
}
if (NETSNMP_KLOOKUP(proc_table_base, (char *) proc_table, bytes) == 0) {
nproc = 0;
snmp_log_perror("Init_HR_SWRun-klookup");
return;
}
}
#endif
current_proc_entry = 0;
}
int
Get_Next_HR_SWRun(void)
{
while (current_proc_entry < nproc) {
#if defined(hpux10) || defined(hpux11)
return proc_table[current_proc_entry++].pst_pid;
#elif defined(solaris2)
return proc_table[current_proc_entry++];
#elif HAVE_KVM_GETPROCS
#if defined(freebsd5) && __FreeBSD_version >= 500014
if (proc_table[current_proc_entry].ki_stat != 0)
return proc_table[current_proc_entry++].ki_pid;
#elif defined(dragonfly) && __DragonFly_version >= 190000
if (proc_table[current_proc_entry].kp_stat != 0)
return proc_table[current_proc_entry++].kp_pid;
#elif defined(openbsd5)
if (proc_table[current_proc_entry].p_stat != 0)
return proc_table[current_proc_entry++].p_pid;
#else
if (proc_table[current_proc_entry].kp_proc.p_stat != 0)
return proc_table[current_proc_entry++].kp_proc.p_pid;
#endif
#elif defined(aix4) || defined(aix5) || defined(aix6)
if (proc_table[current_proc_entry].pi_state != 0)
return proc_table[current_proc_entry++].pi_pid;
else
++current_proc_entry;
#else
if (proc_table[current_proc_entry].p_stat != 0)
return proc_table[current_proc_entry++].p_pid;
else
++current_proc_entry;
#endif
}
return -1;
}
void
End_HR_SWRun(void)
{
current_proc_entry = nproc + 1;
}
#endif
int
count_processes(void)
{
#if !(defined(linux) || defined(cygwin) || defined(hpux10) || defined(hpux11) || defined(solaris2) || HAVE_KVM_GETPROCS || defined(dynix))
int i;
#endif
int total = 0;
Init_HR_SWRun();
#if defined(hpux10) || defined(hpux11) || HAVE_KVM_GETPROCS || defined(solaris2)
total = nproc;
#else
#if defined(aix4) || defined(aix5) || defined(aix6)
for (i = 0; i < nproc; ++i) {
if (proc_table[i].pi_state != 0)
#elif !defined(linux) && !defined(cygwin) && !defined(dynix)
for (i = 0; i < nproc; ++i) {
if (proc_table[i].p_stat != 0)
#else
while (Get_Next_HR_SWRun() != -1) {
#endif
++total;
}
#endif /* !hpux10 && !hpux11 && !HAVE_KVM_GETPROCS && !solaris2 */
End_HR_SWRun();
return total;
}