static int pstat_read(Pss_t* pss, Pss_id_t pid) { register State_t* state = (State_t*)pss->data; int count; if (pid) { if ((count = pstat_getproc(state->pst, sizeof(state->pst[0]), 0, pid)) != 1) return -1; state->pp = state->pst; state->pe = state->pp + count; state->last = 0; } else if (state->pp >= state->pe) { count = state->pe ? (state->pe-1)->pst_idx + 1 : 0; if ((count = pstat_getproc(state->pst, sizeof(state->pst[0]), elementsof(state->pst), count)) < 0) return -1; if (!count) return 0; state->pp = state->pst; state->pe = state->pp + count; state->last = 0; } state->pr = state->pp++; pss->pid = state->pr->pst_pid; return 1; }
static int sigar_pstat_getproc(sigar_t *sigar, sigar_pid_t pid) { int status, num; time_t timenow = time(NULL); if (sigar->pinfo == NULL) { sigar->pinfo = malloc(sizeof(*sigar->pinfo)); } if (sigar->last_pid == pid) { if ((timenow - sigar->last_getprocs) < SIGAR_LAST_PROC_EXPIRE) { return SIGAR_OK; } } sigar->last_pid = pid; sigar->last_getprocs = timenow; if (pstat_getproc(sigar->pinfo, sizeof(*sigar->pinfo), 0, pid) == -1) { return errno; } return SIGAR_OK; }
int sigar_proc_fd_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_fd_t *procfd) { struct pst_status status; int idx=0, n; struct pst_fileinfo2 psf[16]; procfd->total = 0; if (pstat_getproc(&status, sizeof(status), 0, pid) == -1) { return errno; } /* HPUX 11.31 removed the deprecated pstat_getfile call */ while ((n = pstat_getfile2(psf, sizeof(psf[0]), sizeof(psf)/sizeof(psf[0]), idx, pid)) > 0) { procfd->total += n; idx = psf[n-1].psf_fd + 1; } if (n == -1) { return errno; } return SIGAR_OK; }
int sigar_os_proc_list_get(sigar_t *sigar, sigar_proc_list_t *proclist) { int num, idx=0; struct pst_status proctab[PROC_ELTS]; while ((num = pstat_getproc(proctab, sizeof(proctab[0]), PROC_ELTS, idx)) > 0) { int i; for (i=0; i<num; i++) { SIGAR_PROC_LIST_GROW(proclist); proclist->data[proclist->number++] = proctab[i].pst_pid; } idx = proctab[num-1].pst_idx + 1; } if (proclist->number == 0) { return errno; } return SIGAR_OK; }
int ServerProcess::cimserver_kill(int id) { FILE *pid_file; pid_t pid = 0; // open the file containing the CIMServer process ID pid_file = fopen(getPIDFileName(), "r"); if (!pid_file) { return (-1); } // get the pid from the file fscanf(pid_file, "%d\n", &pid); fclose(pid_file); if (pid == 0) { System::removeFile(getPIDFileName()); return (-1); } // // kill the process if it is still alive // #if defined(PEGASUS_OS_HPUX) struct pst_status pstru; int ret_code; ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid); if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, getProcessName())) == 0) { // cimserver is running, kill the process kill(pid, SIGKILL); } #endif #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) if (get_proc(pid) != -1 ) { kill(pid, SIGKILL); } #endif #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) if (isProcRunning(pid)) { kill(pid, SIGKILL); } #endif #if defined(PEGASUS_OS_AIX) if (!aixcimsrvrunning(pid, getProcessName())) kill(pid,SIGKILL); #endif // remove the file System::removeFile(getPIDFileName()); return(0); }
/* * call-seq: * ProcTable.ps(pid=nil) * ProcTable.ps(pid=nil){ |ps| ... } * * In block form, yields a ProcTableStruct for each process entry that you * have rights to. This method returns an array of ProcTableStruct's in * non-block form. * * If a +pid+ is provided, then only a single ProcTableStruct is yielded or * returned, or nil if no process information is found for that +pid+. */ static VALUE proctable_ps(int argc, VALUE *argv) { struct pst_status pst[BURST]; int i, count; int idx = 0; int found = 0; VALUE v_pid = Qnil; VALUE v_arr = rb_ary_new(); rb_scan_args(argc, argv, "01", &v_pid); if(v_pid != Qnil) { struct pst_status pst_single; int n = NUM2INT(v_pid); if(pstat_getproc(&pst_single, sizeof(pst_single), 0, n) > 0) { if(rb_block_given_p()) { rb_yield(proctable_getprocstruct(&pst_single)); return Qnil; } else { return(proctable_getprocstruct(&pst_single)); } } else { return Qnil; /* not found */ } } while ((count = pstat_getproc(pst, sizeof(pst[0]), BURST, idx)) > 0) { for (i = 0; i < count; i++) { if( rb_block_given_p() ) rb_yield(proctable_getprocstruct(&pst[i])); else rb_ary_push(v_arr, proctable_getprocstruct(&pst[i]) ); } idx = pst[count-1].pst_idx + 1; } if(rb_block_given_p()) return Qnil; return v_arr; }
bool getCurrentExecPath(char *buf, size_t len) { struct pst_status psts; if (pstat_getproc(&psts, sizeof(psts), 0, getpid()) == -1) return false; if (pstat_getpathname(buf, len, &psts.pst_fid_text) == -1) return false; return true; }
void closefrom(int lowfd) { struct pst_status pstat; int fd; if (pstat_getproc(&pstat, sizeof(pstat), 0, getpid()) != -1) { for (fd = lowfd; fd <= pstat.pst_highestfd; fd++) (void) close(fd); } else { closefrom_fallback(lowfd); } }
ProcessState GetProcessState(pid_t pid) { struct pst_status proc; if (pstat_getproc(&proc, sizeof(proc), 0, pid) > 0) { return proc.pst_stat == PS_STOP ? PROCESS_STATE_STOPPED : PROCESS_STATE_RUNNING; } else { return PROCESS_STATE_DOES_NOT_EXIST; } }
time_t GetProcessStartTime(pid_t pid) { struct pst_status proc; if (pstat_getproc(&proc, sizeof(proc), 0, pid) > 0) { return proc.pst_start; } else { return PROCESS_START_TIME_UNKNOWN; } }
unsigned int kfi_getPid(const char *proc, unsigned int ppid) { bool error = false; unsigned int pid = 0; int i, count, idx = 0; struct pst_status pst[MAX_PROCS]; while((count = pstat_getproc(&pst[0], sizeof(pst[0]), MAX_PROCS, idx)) > 0 && !error) { for(i = 0; i < count && !error; i++) if(pst[i].pst_ppid == ppid && pst[i].pst_ucomm && 0 == strcmp(pst[i].pst_ucomm, proc)) if(pid) error = true; else pid = pst[i].pst_pid; idx = pst[count - 1].pst_idx + 1; } return error ? 0 : pid; }
/** * Read all processes to initialize the process tree * @param reference reference of ProcessTree * @return treesize>0 if succeeded otherwise 0. */ int initprocesstree_sysdep(ProcessTree_T ** reference) { int i; int treesize; ProcessTree_T *pt; ASSERT(reference); pstat_getdynamic(&pst_dyn, sizeof(struct pst_dynamic), 1, 0); nproc = pst_dyn.psd_activeprocs; if (nproc) RESIZE(psall, nproc * sizeof(struct pst_status)); else return 0; if ((treesize = pstat_getproc(psall, sizeof(struct pst_status), nproc , 0)) == -1) { LogError("system statistic error 1 -- pstat_getproc failed: %s\n", strerror(errno)); return 0; } pt = CALLOC(sizeof(ProcessTree_T), treesize); for (i = 0; i < treesize; i++) { pt[i].pid = psall[i].pst_pid; pt[i].ppid = psall[i].pst_ppid; pt[i].starttime = psall[i].pst_start; pt[i].time = get_float_time(); pt[i].cputime = psall[i].pst_utime + psall[i].pst_stime * 10; pt[i].cpu_percent = (int)(1000. * psall[i].pst_pctcpu / (float)systeminfo.cpus); pt[i].mem_kbyte = (unsigned long)(psall[i].pst_rssize * (page_size / 1024.0)); pt[i].cmdline = (psall[i].pst_cmd && *psall[i].pst_cmd) ? Str_dup(psall[i].pst_cmd) : Str_dup(psall[i].pst_ucomm); if ( psall[i].pst_stat == PS_ZOMBIE ) pt[i].status_flag |= PROCESS_ZOMBIE; } *reference = pt; return treesize; }
PRStatus HpuxProcessStats::getMemUsage(MemUsageInfo *info) { struct pst_status pst_status_buf; if(pstat_getproc(&pst_status_buf,sizeof(pst_status_buf),0,getpid())== -1){ ereport(LOG_FAILURE, XP_GetAdminStr(DBT_ProcessStats_ReadFailed), system_errmsg()); return PR_FAILURE; } /* vtsize--text,vdsize--data, vssize--stack, vshmsize--shared memory, vmmsize--mem-maped files, vusize--U area, viosize-- IO dev mapping */ info->process_size_in_Kbytes = (pst_status_buf.pst_vtsize+pst_status_buf.pst_vdsize +pst_status_buf.pst_vssize+pst_status_buf.pst_vshmsize+pst_status_buf.pst_vmmsize +pst_status_buf.pst_vusize+pst_status_buf.pst_viosize)*page_size_kb; info->process_resident_size_in_Kbytes =(pst_status_buf.pst_rssize)*page_size_kb; /* multiply 0x8000 to convert the format to high byte to conforming the definition of fraction_sys_memory_usage as Solaris. */ info->fraction_system_memory_usage = info->process_resident_size_in_Kbytes*0x8000/mem_total_kb; return PR_SUCCESS; }
int sigar_os_proc_args_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_args_t *procargs) { char *args, *arg; #ifdef PSTAT_GETCOMMANDLINE char buf[1024]; /* kernel limit */ # ifdef pstat_getcommandline /* 11i v2 + */ if (pstat_getcommandline(buf, sizeof(buf), sizeof(buf[0]), pid) == -1) { return errno; } # else union pstun pu; pu.pst_command = buf; if (pstat(PSTAT_GETCOMMANDLINE, pu, sizeof(buf), sizeof(buf[0]), pid) == -1) { return errno; } # endif /* pstat_getcommandline */ args = buf; #else struct pst_status status; if (pstat_getproc(&status, sizeof(status), 0, pid) == -1) { return errno; } args = status.pst_cmd; #endif while (*args && (arg = sigar_getword(&args, ' '))) { SIGAR_PROC_ARGS_GROW(procargs); procargs->data[procargs->number++] = arg; } return SIGAR_OK; }
int sigar_proc_exe_get(sigar_t *sigar, sigar_pid_t pid, sigar_proc_exe_t *procexe) { #ifdef __pst_fid /* 11.11+ */ int rc; struct pst_status status; if (pstat_getproc(&status, sizeof(status), 0, pid) == -1) { return errno; } rc = pstat_getpathname(procexe->cwd, sizeof(procexe->cwd), &status.pst_fid_cdir); if (rc == -1) { return errno; } rc = pstat_getpathname(procexe->name, sizeof(procexe->name), &status.pst_fid_text); if (rc == -1) { return errno; } rc = pstat_getpathname(procexe->root, sizeof(procexe->root), &status.pst_fid_rdir); if (rc == -1) { return errno; } return SIGAR_OK; #else return SIGAR_ENOTIMPL; /* 11.00 */ #endif }
DWORD CTGetPidOfCmdLine( PCSTR programName, PCSTR programFilename, PCSTR cmdLine, uid_t owner, pid_t *pid, size_t *count ) { DWORD ceError = ERROR_NOT_SUPPORTED; size_t fillCount = 0; size_t foundCount = 0; struct stat findStat; #if HAVE_DECL_PSTAT_GETPROC //HPUX should have this struct pst_status mystatus; struct pst_status status[10]; int inBuffer; int i; #endif #ifdef HAVE_STRUCT_PSINFO //Solaris and AIX should have this DIR *dir = NULL; struct dirent *dirEntry = NULL; PSTR filePath = NULL; struct psinfo infoStruct; FILE *infoFile = NULL; struct stat compareStat; BOOLEAN bFileExists; #endif #if defined(HAVE_KVM_GETPROCS) && HAVE_DECL_KERN_PROC_PATHNAME //FreeBSD has this char pathBuffer[MAXPATHLEN]; size_t len; int unfilteredCount; kvm_t *kd = NULL; struct kinfo_proc *procs; int i; struct kinfo_proc *pos; int sysctlName[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, 0 }; #endif if(count) { fillCount = *count; *count = 0; } else if(pid != NULL) fillCount = 1; if(programFilename != NULL) { while(stat(programFilename, &findStat) < 0) { if(errno == EINTR) continue; GCE(ceError = LwMapErrnoToLwError(errno)); } } #if HAVE_DECL_PSTAT_GETPROC //First get the process info for this process inBuffer = pstat_getproc(&mystatus, sizeof(mystatus), 0, getpid()); if(inBuffer != 1) GCE(ceError = LwMapErrnoToLwError(errno)); //Now look at all processes inBuffer = pstat_getproc(status, sizeof(status[0]), sizeof(status)/sizeof(status[0]), 0); if(inBuffer < 0) GCE(ceError = LwMapErrnoToLwError(errno)); while(inBuffer > 0) { for(i = 0; i < inBuffer; i++) { if(memcmp(&mystatus.pst_rdir, &status[i].pst_rdir, sizeof(mystatus.pst_rdir))) { /* This process has a different root directory (it is being run via a chroot). Let's not count this process as a match. */ continue; } if (owner != (uid_t)-1 && owner != status[i].pst_euid) { continue; } if (programName != NULL && strcmp(status[i].pst_ucomm, programName)) { continue; } if (cmdLine != NULL && strcmp(status[i].pst_cmd, cmdLine)) { continue; } if(programFilename != NULL && ( status[i].pst_text.psf_fileid != findStat.st_ino || status[i].pst_text.psf_fsid.psfs_id != findStat.st_dev || status[i].pst_text.psf_fsid.psfs_type != findStat.st_fstype )) { continue; } //This is a match if(foundCount < fillCount) pid[foundCount] = status[i].pst_pid; foundCount++; } //Continue looking at the process list where we left off inBuffer = pstat_getproc(status, sizeof(status[0]), sizeof(status)/sizeof(status[0]), status[inBuffer - 1].pst_idx + 1); if(inBuffer < 0) GCE(ceError = LwMapErrnoToLwError(errno)); } ceError = ERROR_SUCCESS; #endif #ifdef HAVE_STRUCT_PSINFO if ((dir = opendir("/proc")) == NULL) { GCE(ceError = LwMapErrnoToLwError(errno)); } while(1) { errno = 0; dirEntry = readdir(dir); if(dirEntry == NULL) { if(errno != 0) GCE(ceError = LwMapErrnoToLwError(errno)); else { //No error here. We simply read the last entry break; } } if(dirEntry->d_name[0] == '.') continue; // On AIX, there is a /proc/sys which does not contain a psinfo if(!isdigit((int)dirEntry->d_name[0])) continue; CT_SAFE_FREE_STRING(filePath); GCE(ceError = CTAllocateStringPrintf(&filePath, "/proc/%s/psinfo", dirEntry->d_name)); GCE(ceError = CTCheckFileOrLinkExists(filePath, &bFileExists)); if(!bFileExists) { // On AIX 6.1, a defunct process can lack a psinfo file. continue; } GCE(ceError = CTSafeCloseFile(&infoFile)); GCE(ceError = CTOpenFile(filePath, "r", &infoFile)); if(fread(&infoStruct, sizeof(infoStruct), 1, infoFile) != 1) { GCE(ceError = LwMapErrnoToLwError(errno)); } if (owner != (uid_t)-1 && owner != infoStruct.pr_euid) { continue; } if (programName != NULL && strcmp(infoStruct.pr_fname, programName)) { continue; } if (cmdLine != NULL && strcmp(infoStruct.pr_psargs, cmdLine)) { continue; } if(programFilename != NULL) { CT_SAFE_FREE_STRING(filePath); GCE(ceError = CTAllocateStringPrintf(&filePath, "/proc/%s/object/a.out", dirEntry->d_name)); while(stat(filePath, &compareStat) < 0) { if(errno == EINTR) continue; if(errno == ENOENT || errno == ENOTDIR) { //This process wasn't executed from a file? goto not_match; } GCE(ceError = LwMapErrnoToLwError(errno)); } if(findStat.st_ino != compareStat.st_ino) continue; if(findStat.st_dev != compareStat.st_dev) continue; if(findStat.st_rdev != compareStat.st_rdev) continue; } //This is a match if(foundCount < fillCount) pid[foundCount] = infoStruct.pr_pid; foundCount++; not_match: ; } #endif #if defined(HAVE_KVM_GETPROCS) && HAVE_DECL_KERN_PROC_PATHNAME kd = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, NULL); if (kd == NULL) GCE(ceError = DWORD_ACCESS_DENIED); procs = kvm_getprocs(kd, KERN_PROC_PROC, 0, &unfilteredCount); if (procs == NULL) GCE(ceError = DWORD_ACCESS_DENIED); pos = procs; for(i = 0; i < unfilteredCount; i++, pos = (struct kinfo_proc *)((char *)pos + pos->ki_structsize)) { if (owner != (uid_t)-1 && owner != pos->ki_uid) { continue; } if (programName != NULL && strcmp(pos->ki_comm, programName)) { continue; } if (cmdLine != NULL) { char **args = kvm_getargv(kd, pos, 0); char **argPos = args; PCSTR cmdLinePos = cmdLine; while (*cmdLinePos != '\0') { if (argPos == NULL || *argPos == NULL) break; if (strncmp(cmdLinePos, *argPos, strlen(*argPos))) break; cmdLinePos += strlen(*argPos); argPos++; if(cmdLinePos[0] == ' ') cmdLinePos++; } if(*cmdLinePos != '\0' || (argPos != NULL && *argPos != NULL)) { //not a match continue; } } if (programFilename != NULL) { pathBuffer[0] = '\0'; if (pos->ki_textvp != NULL) { sysctlName[3] = pos->ki_pid; len = sizeof(pathBuffer); if( sysctl(sysctlName, 4, pathBuffer, &len, NULL, 0) < 0) { /* If the executable path does not exist (e.g. because the file was deleted after the program started), move on */ if (errno == ENOENT) continue; GCE(ceError = LwMapErrnoToLwError(errno)); } } if(strcmp(programFilename, pathBuffer)) continue; } //This is a match if(foundCount < fillCount) pid[foundCount] = pos->ki_pid; foundCount++; } ceError = ERROR_SUCCESS; #endif if(count) *count = foundCount; else if(!ceError && foundCount == 0) ceError = ERROR_PROC_NOT_FOUND; cleanup: #ifdef HAVE_STRUCT_PSINFO if(dir != NULL) closedir(dir); CT_SAFE_FREE_STRING(filePath); CTSafeCloseFile(&infoFile); #endif #if defined(HAVE_KVM_GETPROCS) && HAVE_DECL_KERN_PROC_PATHNAME if(kd != NULL) { kvm_close(kd); } #endif return ceError; }
void OS_get_table() { struct pst_status pst[BURST]; int i, count; int idx = 0; char buff[256]; /* used to format %cpu which is the only float. */ while ((count = pstat_getproc(pst, sizeof(pst[0]), BURST, idx)) > 0) { for (i = 0; i < count; i++) { sprintf(buff, "%f", pst[i].pst_pctcpu * 100); bless_into_proc(Format, Fields, (long) pst[i].pst_uid, (long) pst[i].pst_pid, (long) pst[i].pst_ppid, (long) pst[i].pst_dsize, (long) pst[i].pst_tsize, (long) pst[i].pst_ssize, (long) pst[i].pst_nice, (long) makedev(pst[i].pst_term.psd_major, pst[i].pst_term.psd_minor), (long) pst[i].pst_pgrp, (long) pst[i].pst_pri, (long) pst[i].pst_addr, (long) pst[i].pst_cpu, (long) pst[i].pst_utime, (long) pst[i].pst_stime, (long) pst[i].pst_start, (long) pst[i].pst_flag, States[pst[i].pst_stat], (long) pst[i].pst_wchan, (long) pst[i].pst_procnum, pst[i].pst_cmd, pst[i].pst_ucomm, (long) pst[i].pst_cptickstotal/100, (long) pst[i].pst_cpticks, (long) pst[i].pst_cptickstotal, (long) pst[i].pst_fss, buff, (long) pst[i].pst_rssize, (long) pst[i].pst_suid, pst[i].pst_ucomm, (long) pst[i].pst_shmsize, (long) pst[i].pst_mmsize, (long) pst[i].pst_usize, (long) pst[i].pst_iosize, (long) pst[i].pst_vtsize, (long) pst[i].pst_vdsize, (long) pst[i].pst_vssize, (long) pst[i].pst_vshmsize, (long) pst[i].pst_vmmsize, (long) pst[i].pst_vusize, (long) pst[i].pst_viosize, (long) pst[i].pst_minorfaults, (long) pst[i].pst_majorfaults, (long) pst[i].pst_nswap, (long) pst[i].pst_nsignals, (long) pst[i].pst_msgrcv, (long) pst[i].pst_msgsnd, (long) pst[i].pst_maxrss, (long) pst[i].pst_sid, (long) pst[i].pst_schedpolicy, (long) pst[i].pst_ticksleft, "", "", "", (long) pst[i].pst_highestfd, (long) pst[i].pst_euid, (long) pst[i].pst_egid, (long) pst[i].pst_ioch, "", "", "", (long) pst[i].pst_gid, (long) pst[i].pst_lwpid); } idx = pst[count-1].pst_idx + 1; } }
/* Specification. */ #include "getprogname.h" #include <errno.h> /* get program_invocation_name declaration */ #include <stdlib.h> /* get __argv declaration */ #ifdef _AIX # include <unistd.h> # include <procinfo.h> # include <string.h> #endif #ifdef __MVS__ # ifndef _OPEN_SYS # define _OPEN_SYS # endif # include <string.h> # include <sys/ps.h> #endif #ifdef __hpux # include <unistd.h> # include <sys/param.h> # include <sys/pstat.h> # include <string.h> #endif #include "dirname.h" #ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */ char const * getprogname (void) { # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* glibc, BeOS */ /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */ return program_invocation_short_name; # elif HAVE_DECL_PROGRAM_INVOCATION_NAME /* glibc, BeOS */ /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */ return last_component (program_invocation_name); # elif HAVE_GETEXECNAME /* Solaris */ /* http://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrb1/index.html */ const char *p = getexecname (); if (!p) p = "?"; return last_component (p); # elif HAVE_DECL___ARGV /* mingw, MSVC */ /* https://msdn.microsoft.com/en-us/library/dn727674.aspx */ const char *p = __argv && __argv[0] ? __argv[0] : "?"; return last_component (p); # elif HAVE_VAR___PROGNAME /* OpenBSD, QNX */ /* http://man.openbsd.org/style.9 */ /* http://www.qnx.de/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino_lib_ref%2Fp%2F__progname.html */ /* Be careful to declare this only when we absolutely need it (OpenBSD 5.1), rather than when it's available. Otherwise, its mere declaration makes program_invocation_short_name malfunction (have zero length) with Fedora 25's glibc. */ extern char *__progname; const char *p = __progname; return p && p[0] ? p : "?"; # elif _AIX /* AIX */ /* Idea by Bastien ROUCARIÈS, http://lists.gnu.org/archive/html/bug-gnulib/2010-12/msg00095.html Reference: http:// ibm.biz/knowctr#ssw_aix_53/com.ibm.aix.basetechref/doc/basetrf1/getprocs.htm */ static char *p; static int first = 1; if (first) { first = 0; pid_t pid = getpid (); struct procentry64 procs; p = (0 < getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1) ? strdup (procs.pi_comm) : NULL); if (!p) p = "?"; } return p; # elif defined __hpux static char *p; static int first = 1; if (first) { first = 0; pid_t pid = getpid (); struct pst_status status; p = (0 < pstat_getproc (&status, sizeof status, 0, pid) ? strdup (status.pst_ucomm) : NULL); if (!p) p = "?"; } return p; # elif __MVS__ /* z/OS */ /* https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rtwgetp.htm */ static char *p = "?"; static int first = 1; if (first) { pid_t pid = getpid (); int token; W_PSPROC buf; first = 0; memset (&buf, 0, sizeof(buf)); buf.ps_cmdptr = (char *) malloc (buf.ps_cmdlen = PS_CMDBLEN_LONG); buf.ps_conttyptr = (char *) malloc (buf.ps_conttylen = PS_CONTTYBLEN); buf.ps_pathptr = (char *) malloc (buf.ps_pathlen = PS_PATHBLEN); if (buf.ps_cmdptr && buf.ps_conttyptr && buf.ps_pathptr) { for (token = 0; token >= 0; token = w_getpsent (token, &buf, sizeof(buf))) { if (token > 0 && buf.ps_pid == pid) { char *s = strdup (last_component (buf.ps_pathptr)); if (s) p = s; break; } } } free (buf.ps_cmdptr); free (buf.ps_conttyptr); free (buf.ps_pathptr); } return p; # else # error "getprogname module not ported to this OS" # endif }
sg_process_stats *sg_get_process_stats(int *entries){ VECTOR_DECLARE_STATIC(proc_state, sg_process_stats, 64, proc_state_init, proc_state_destroy); int proc_state_size = 0; sg_process_stats *proc_state_ptr; #ifdef HPUX struct pst_status pstat_procinfo[PROCESS_BATCH]; long procidx = 0; long long pagesize; int num, i; #endif #ifdef AIX struct procentry64 *procs = NULL; long long pagesize; int fetched = 0; pid_t index = 0; unsigned proc_idx; time_t utime, stime; int ncpus; struct timeval now_tval; double now_time; char cmndline[ARG_MAX]; char comm[ARG_MAX]; struct procentry64 curproc_for_getargs; #define PROCS_TO_FETCH 1000 #endif #ifdef ALLBSD int mib[4]; size_t size; struct kinfo_proc *kp_stats; int procs, i; char *proctitle; #if (defined(FREEBSD) && !defined(FREEBSD5)) || defined(DFBSD) kvm_t *kvmd; char **args, **argsp; int argslen = 0; #else long buflen; char *p, *proctitletmp; #endif #ifdef NETBSD2 int lwps; struct kinfo_lwp *kl_stats; #endif #endif #if defined(SOLARIS) || defined(LINUX) DIR *proc_dir; struct dirent *dir_entry; char filename[MAX_FILE_LENGTH]; FILE *f; #ifdef SOLARIS psinfo_t process_info; #endif #ifdef LINUX char s; /* If someone has a executable of 4k filename length, they deserve to get it truncated :) */ char ps_name[4096]; char *ptr; VECTOR_DECLARE_STATIC(psargs, char, 128, NULL, NULL); unsigned long stime, utime, starttime; int x; int fn; int len; int rc; time_t uptime; long tickspersec; #endif #ifdef LINUX if ((f=fopen("/proc/uptime", "r")) == NULL) { sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/uptime"); return NULL; } if((fscanf(f,"%lu %*d",&uptime)) != 1){ sg_set_error(SG_ERROR_PARSE, NULL); return NULL; } fclose(f); #endif if((proc_dir=opendir(PROC_LOCATION))==NULL){ sg_set_error_with_errno(SG_ERROR_OPENDIR, PROC_LOCATION); return NULL; } while((dir_entry=readdir(proc_dir))!=NULL){ if(atoi(dir_entry->d_name) == 0) continue; #ifdef SOLARIS snprintf(filename, MAX_FILE_LENGTH, "/proc/%s/psinfo", dir_entry->d_name); #endif #ifdef LINUX snprintf(filename, MAX_FILE_LENGTH, "/proc/%s/stat", dir_entry->d_name); #endif if((f=fopen(filename, "r"))==NULL){ /* Open failed.. Process since vanished, or the path was too long. * Ah well, move onwards to the next one */ continue; } #ifdef SOLARIS fread(&process_info, sizeof(psinfo_t), 1, f); fclose(f); #endif if (VECTOR_RESIZE(proc_state, proc_state_size + 1) < 0) { return NULL; } proc_state_ptr = proc_state+proc_state_size; #ifdef SOLARIS proc_state_ptr->pid = process_info.pr_pid; proc_state_ptr->parent = process_info.pr_ppid; proc_state_ptr->pgid = process_info.pr_pgid; proc_state_ptr->uid = process_info.pr_uid; proc_state_ptr->euid = process_info.pr_euid; proc_state_ptr->gid = process_info.pr_gid; proc_state_ptr->egid = process_info.pr_egid; proc_state_ptr->proc_size = (process_info.pr_size) * 1024; proc_state_ptr->proc_resident = (process_info.pr_rssize) * 1024; proc_state_ptr->time_spent = process_info.pr_time.tv_sec; proc_state_ptr->cpu_percent = (process_info.pr_pctcpu * 100.0) / 0x8000; proc_state_ptr->nice = (int)process_info.pr_lwp.pr_nice - 20; if (sg_update_string(&proc_state_ptr->process_name, process_info.pr_fname) < 0) { return NULL; } if (sg_update_string(&proc_state_ptr->proctitle, process_info.pr_psargs) < 0) { return NULL; } switch (process_info.pr_lwp.pr_state) { case 1: proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; break; case 2: case 5: proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; break; case 3: proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; break; case 4: proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; break; } #endif #ifdef LINUX x = fscanf(f, "%d %4096s %c %d %d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu %*d %*d %*d %d %*d %*d %lu %llu %llu %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %*d\n", &(proc_state_ptr->pid), ps_name, &s, &(proc_state_ptr->parent), &(proc_state_ptr->pgid), &utime, &stime, &(proc_state_ptr->nice), &starttime, &(proc_state_ptr->proc_size), &(proc_state_ptr->proc_resident)); /* +3 becuase man page says "Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes." */ proc_state_ptr->proc_resident = (proc_state_ptr->proc_resident + 3) * getpagesize(); switch (s) { case 'S': proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; break; case 'R': proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; break; case 'Z': proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; break; case 'T': case 'D': proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; break; } /* pa_name[0] should = '(' */ ptr = strchr(&ps_name[1], ')'); if(ptr !=NULL) *ptr='\0'; if (sg_update_string(&proc_state_ptr->process_name, &ps_name[1]) < 0) { return NULL; } /* cpu */ proc_state_ptr->cpu_percent = (100.0 * (utime + stime)) / ((uptime * 100.0) - starttime); tickspersec = sysconf (_SC_CLK_TCK); if (tickspersec < 0) { proc_state_ptr->time_spent = 0; } else { proc_state_ptr->time_spent = (utime + stime) / tickspersec; } fclose(f); /* uid / gid */ snprintf(filename, MAX_FILE_LENGTH, "/proc/%s/status", dir_entry->d_name); if ((f=fopen(filename, "r")) == NULL) { /* Open failed.. Process since vanished, or the path was too long. * Ah well, move onwards to the next one */ continue; } if((ptr=sg_f_read_line(f, "Uid:"))==NULL){ fclose(f); continue; } sscanf(ptr, "Uid:\t%d\t%d\t%*d\t%*d\n", &(proc_state_ptr->uid), &(proc_state_ptr->euid)); if((ptr=sg_f_read_line(f, "Gid:"))==NULL){ fclose(f); continue; } sscanf(ptr, "Gid:\t%d\t%d\t%*d\t%*d\n", &(proc_state_ptr->gid), &(proc_state_ptr->egid)); fclose(f); /* proctitle */ snprintf(filename, MAX_FILE_LENGTH, "/proc/%s/cmdline", dir_entry->d_name); if((fn=open(filename, O_RDONLY)) == -1){ /* Open failed.. Process since vanished, or the path was too long. * Ah well, move onwards to the next one */ continue; } #define READ_BLOCK_SIZE 128 len = 0; do { if (VECTOR_RESIZE(psargs, len + READ_BLOCK_SIZE) < 0) { return NULL; } rc = read(fn, psargs + len, READ_BLOCK_SIZE); if (rc > 0) { len += rc; } } while (rc == READ_BLOCK_SIZE); close(fn); if (rc == -1) { /* Read failed; move on. */ continue; } /* Turn \0s into spaces within the command line. */ ptr = psargs; for(x = 0; x < len; x++) { if (*ptr == '\0') *ptr = ' '; ptr++; } if (len == 0) { /* We want psargs to be NULL. */ if (VECTOR_RESIZE(psargs, 0) < 0) { return NULL; } } else { /* Not empty, so append a \0. */ if (VECTOR_RESIZE(psargs, len + 1) < 0) { return NULL; } psargs[len] = '\0'; } if (sg_update_string(&proc_state_ptr->proctitle, psargs) < 0) { return NULL; } #endif proc_state_size++; } closedir(proc_dir); #endif #ifdef ALLBSD mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_ALL; if(sysctl(mib, 3, NULL, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_KERN.KERN_PROC.KERN_PROC_ALL"); return NULL; } procs = size / sizeof(struct kinfo_proc); kp_stats = sg_malloc(size); if(kp_stats == NULL) { return NULL; } memset(kp_stats, 0, size); if(sysctl(mib, 3, kp_stats, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_KERN.KERN_PROC.KERN_PROC_ALL"); free(kp_stats); return NULL; } #if (defined(FREEBSD) && !defined(FREEBSD5)) || defined(DFBSD) kvmd = sg_get_kvm2(); #endif for (i = 0; i < procs; i++) { const char *name; #ifdef FREEBSD5 if (kp_stats[i].ki_stat == 0) { #else if (kp_stats[i].kp_proc.p_stat == 0) { #endif /* FreeBSD 5 deliberately overallocates the array that * the sysctl returns, so we'll get a few junk * processes on the end that we have to ignore. (Search * for "overestimate by 5 procs" in * src/sys/kern/kern_proc.c for more details.) */ continue; } if (VECTOR_RESIZE(proc_state, proc_state_size + 1) < 0) { return NULL; } proc_state_ptr = proc_state+proc_state_size; #ifdef FREEBSD5 name = kp_stats[i].ki_comm; #elif defined(DFBSD) name = kp_stats[i].kp_thread.td_comm; #else name = kp_stats[i].kp_proc.p_comm; #endif if (sg_update_string(&proc_state_ptr->process_name, name) < 0) { return NULL; } #if defined(FREEBSD5) || defined(NETBSD) || defined(OPENBSD) #ifdef FREEBSD5 mib[2] = KERN_PROC_ARGS; mib[3] = kp_stats[i].ki_pid; #else mib[1] = KERN_PROC_ARGS; mib[2] = kp_stats[i].kp_proc.p_pid; mib[3] = KERN_PROC_ARGV; #endif free(proc_state_ptr->proctitle); proc_state_ptr->proctitle = NULL; /* Starting size - we'll double this straight away */ #define PROCTITLE_START_SIZE 64 buflen = PROCTITLE_START_SIZE; size = buflen; proctitle = NULL; do { if((long) size >= buflen) { buflen *= 2; size = buflen; proctitletmp = sg_realloc(proctitle, buflen); if(proctitletmp == NULL) { free(proctitle); proctitle = NULL; proc_state_ptr->proctitle = NULL; size = 0; break; } proctitle = proctitletmp; bzero(proctitle, buflen); } if(sysctl(mib, 4, proctitle, &size, NULL, 0) < 0) { free(proctitle); proctitle = NULL; proc_state_ptr->proctitle = NULL; size = 0; break; } } while((long) size >= buflen); if(size > 0) { proc_state_ptr->proctitle = sg_malloc(size+1); if(proc_state_ptr->proctitle == NULL) { return NULL; } p = proctitle; #ifdef OPENBSD /* On OpenBSD, this value has the argv pointers (which * are terminated by a NULL) at the front, so we have * to skip over them to get to the strings. */ while (*(char ***)p != NULL) { p += sizeof(char **); } p += sizeof(char **); #endif proc_state_ptr->proctitle[0] = '\0'; do { sg_strlcat(proc_state_ptr->proctitle, p, size+1); sg_strlcat(proc_state_ptr->proctitle, " ", size+1); p += strlen(p) + 1; } while (p < proctitle + size); free(proctitle); proctitle = NULL; /* remove trailing space */ proc_state_ptr->proctitle[strlen(proc_state_ptr->proctitle)-1] = '\0'; } else { if(proctitle != NULL) { free(proctitle); proctitle = NULL; } proc_state_ptr->proctitle = NULL; } #else free(proc_state_ptr->proctitle); proc_state_ptr->proctitle = NULL; if(kvmd != NULL) { args = kvm_getargv(kvmd, &(kp_stats[i]), 0); if(args != NULL) { argsp = args; while(*argsp != NULL) { argslen += strlen(*argsp) + 1; argsp++; } proctitle = sg_malloc(argslen + 1); proctitle[0] = '\0'; if(proctitle == NULL) { return NULL; } while(*args != NULL) { sg_strlcat(proctitle, *args, argslen + 1); sg_strlcat(proctitle, " ", argslen + 1); args++; } /* remove trailing space */ proctitle[strlen(proctitle)-1] = '\0'; proc_state_ptr->proctitle = proctitle; } else { proc_state_ptr->proctitle = NULL; } } else { proc_state_ptr->proctitle = NULL; } #endif #ifdef FREEBSD5 proc_state_ptr->pid = kp_stats[i].ki_pid; proc_state_ptr->parent = kp_stats[i].ki_ppid; proc_state_ptr->pgid = kp_stats[i].ki_pgid; #else proc_state_ptr->pid = kp_stats[i].kp_proc.p_pid; proc_state_ptr->parent = kp_stats[i].kp_eproc.e_ppid; proc_state_ptr->pgid = kp_stats[i].kp_eproc.e_pgid; #endif #ifdef FREEBSD5 proc_state_ptr->uid = kp_stats[i].ki_ruid; proc_state_ptr->euid = kp_stats[i].ki_uid; proc_state_ptr->gid = kp_stats[i].ki_rgid; proc_state_ptr->egid = kp_stats[i].ki_svgid; #elif defined(DFBSD) proc_state_ptr->uid = kp_stats[i].kp_eproc.e_ucred.cr_ruid; proc_state_ptr->euid = kp_stats[i].kp_eproc.e_ucred.cr_svuid; proc_state_ptr->gid = kp_stats[i].kp_eproc.e_ucred.cr_rgid; proc_state_ptr->egid = kp_stats[i].kp_eproc.e_ucred.cr_svgid; #else proc_state_ptr->uid = kp_stats[i].kp_eproc.e_pcred.p_ruid; proc_state_ptr->euid = kp_stats[i].kp_eproc.e_pcred.p_svuid; proc_state_ptr->gid = kp_stats[i].kp_eproc.e_pcred.p_rgid; proc_state_ptr->egid = kp_stats[i].kp_eproc.e_pcred.p_svgid; #endif #ifdef FREEBSD5 proc_state_ptr->proc_size = kp_stats[i].ki_size; /* This is in pages */ proc_state_ptr->proc_resident = kp_stats[i].ki_rssize * getpagesize(); /* This is in microseconds */ proc_state_ptr->time_spent = kp_stats[i].ki_runtime / 1000000; proc_state_ptr->cpu_percent = ((double)kp_stats[i].ki_pctcpu / FSCALE) * 100.0; proc_state_ptr->nice = kp_stats[i].ki_nice; #else proc_state_ptr->proc_size = kp_stats[i].kp_eproc.e_vm.vm_map.size; /* This is in pages */ proc_state_ptr->proc_resident = kp_stats[i].kp_eproc.e_vm.vm_rssize * getpagesize(); #if defined(NETBSD) || defined(OPENBSD) proc_state_ptr->time_spent = kp_stats[i].kp_proc.p_rtime.tv_sec; #elif defined(DFBSD) proc_state_ptr->time_spent = ( kp_stats[i].kp_thread.td_uticks + kp_stats[i].kp_thread.td_sticks + kp_stats[i].kp_thread.td_iticks ) / 1000000; #else /* This is in microseconds */ proc_state_ptr->time_spent = kp_stats[i].kp_proc.p_runtime / 1000000; #endif proc_state_ptr->cpu_percent = ((double)kp_stats[i].kp_proc.p_pctcpu / FSCALE) * 100.0; proc_state_ptr->nice = kp_stats[i].kp_proc.p_nice; #endif #ifdef NETBSD2 { size_t size; int mib[5]; mib[0] = CTL_KERN; mib[1] = KERN_LWP; mib[2] = kp_stats[i].kp_proc.p_pid; mib[3] = sizeof(struct kinfo_lwp); mib[4] = 0; if(sysctl(mib, 5, NULL, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_KERN.KERN_LWP.pid.structsize.0"); return NULL; } lwps = size / sizeof(struct kinfo_lwp); mib[4] = lwps; kl_stats = sg_malloc(size); if(kl_stats == NULL) { return NULL; } if(sysctl(mib, 5, kl_stats, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_KERN.KERN_LWP.pid.structsize.buffersize"); return NULL; } } switch(kp_stats[i].kp_proc.p_stat) { case SIDL: proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; break; case SACTIVE: { int i; for(i = 0; i < lwps; i++) { switch(kl_stats[i].l_stat) { case LSONPROC: case LSRUN: proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; goto end; case LSSLEEP: proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; goto end; case LSSTOP: case LSSUSPENDED: proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; goto end; } proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; } end: ; } break; case SSTOP: proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; break; case SZOMB: proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; break; default: proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; break; } free(kl_stats); #else #ifdef FREEBSD5 switch (kp_stats[i].ki_stat) { #else switch (kp_stats[i].kp_proc.p_stat) { #endif case SIDL: case SRUN: #ifdef SONPROC case SONPROC: /* NetBSD */ #endif proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; break; case SSLEEP: #ifdef SWAIT case SWAIT: /* FreeBSD 5 */ #endif #ifdef SLOCK case SLOCK: /* FreeBSD 5 */ #endif proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; break; case SSTOP: proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; break; case SZOMB: #ifdef SDEAD case SDEAD: /* OpenBSD & NetBSD */ #endif proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; break; default: proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; break; } #endif proc_state_size++; } free(kp_stats); #endif #ifdef HPUX if ((pagesize = sysconf(_SC_PAGESIZE)) == -1) { sg_set_error_with_errno(SG_ERROR_SYSCONF, "_SC_PAGESIZE"); return NULL; } while (1) { num = pstat_getproc(pstat_procinfo, sizeof pstat_procinfo[0], PROCESS_BATCH, procidx); if (num == -1) { sg_set_error_with_errno(SG_ERROR_PSTAT, "pstat_getproc"); return NULL; } else if (num == 0) { break; } for (i = 0; i < num; i++) { struct pst_status *pi = &pstat_procinfo[i]; if (VECTOR_RESIZE(proc_state, proc_state_size + 1) < 0) { return NULL; } proc_state_ptr = proc_state+proc_state_size; proc_state_ptr->pid = pi->pst_pid; proc_state_ptr->parent = pi->pst_ppid; proc_state_ptr->pgid = pi->pst_pgrp; proc_state_ptr->uid = pi->pst_uid; proc_state_ptr->euid = pi->pst_euid; proc_state_ptr->gid = pi->pst_gid; proc_state_ptr->egid = pi->pst_egid; proc_state_ptr->proc_size = (pi->pst_dsize + pi->pst_tsize + pi->pst_ssize) * pagesize; proc_state_ptr->proc_resident = pi->pst_rssize * pagesize; proc_state_ptr->time_spent = pi->pst_time; proc_state_ptr->cpu_percent = (pi->pst_pctcpu * 100.0) / 0x8000; proc_state_ptr->nice = pi->pst_nice; if (sg_update_string(&proc_state_ptr->process_name, pi->pst_ucomm) < 0) { return NULL; } if (sg_update_string(&proc_state_ptr->proctitle, pi->pst_cmd) < 0) { return NULL; } switch (pi->pst_stat) { case PS_SLEEP: proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; break; case PS_RUN: proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; break; case PS_STOP: proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; break; case PS_ZOMBIE: proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; break; case PS_IDLE: case PS_OTHER: proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; break; } proc_state_size++; } procidx = pstat_procinfo[num - 1].pst_idx + 1; } #endif #ifdef AIX #define TVALU_TO_SEC(x) ((x).tv_sec + ((double)((x).tv_usec) / 1000000.0)) #define TVALN_TO_SEC(x) ((x).tv_sec + ((double)((x).tv_usec) / 1000000000.0)) ncpus = sysconf(_SC_NPROCESSORS_ONLN); if( -1 == ncpus ) { ncpus = 1; /* sysconf error - assume 1 */ } if ((pagesize = sysconf(_SC_PAGESIZE)) == -1) { sg_set_error_with_errno(SG_ERROR_SYSCONF, "_SC_PAGESIZE"); return NULL; } proc_idx = 0; procs = /* (struct procentry64 *) */ malloc(sizeof(*procs) * PROCS_TO_FETCH); if(NULL == procs) { sg_set_error_with_errno(SG_ERROR_MALLOC, "sg_get_process_stats"); return 0; } gettimeofday(&now_tval, 0); now_time = TVALU_TO_SEC(now_tval); /* keep on grabbing chunks of processes until getprocs returns a smaller block than we asked for */ do { int i; fetched = getprocs64(procs, sizeof(*procs), NULL, 0, &index, PROCS_TO_FETCH); if (VECTOR_RESIZE(proc_state, proc_state_size + fetched) < 0) { sg_set_error_with_errno(SG_ERROR_MALLOC, "sg_get_process_stats"); free(procs); return NULL; } for( i = 0; i < fetched; ++i ) { struct procentry64 *pi = procs+i; int zombie = 0; proc_state_ptr = proc_state + proc_idx; zombie = 0; /* set a descriptive name for the process state */ switch( pi->pi_state ) { case SSLEEP: proc_state_ptr->state = SG_PROCESS_STATE_SLEEPING; break; case SRUN: proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; break; case SZOMB: proc_state_ptr->state = SG_PROCESS_STATE_ZOMBIE; zombie = 1; break; case SSTOP: proc_state_ptr->state = SG_PROCESS_STATE_STOPPED; break; case SACTIVE: proc_state_ptr->state = SG_PROCESS_STATE_RUNNING; break; case SIDL: default: proc_state_ptr->state = SG_PROCESS_STATE_UNKNOWN; break; } if( zombie ) { utime = pi->pi_utime; stime = pi->pi_stime; } else { utime = TVALN_TO_SEC(pi->pi_ru.ru_utime) + TVALN_TO_SEC(pi->pi_cru.ru_utime); stime = TVALN_TO_SEC(pi->pi_ru.ru_stime) + TVALN_TO_SEC(pi->pi_cru.ru_stime); } proc_state_ptr->pid = pi->pi_pid; proc_state_ptr->parent = pi->pi_ppid; proc_state_ptr->pgid = pi->pi_pgrp; proc_state_ptr->uid = pi->pi_cred.crx_ruid; proc_state_ptr->euid = pi->pi_cred.crx_uid; proc_state_ptr->gid = pi->pi_cred.crx_rgid; proc_state_ptr->egid = pi->pi_cred.crx_gid; proc_state_ptr->proc_size = pi->pi_size; proc_state_ptr->proc_resident = pi->pi_drss + pi->pi_trss; /* XXX might be wrong, see P::PT */ proc_state_ptr->time_spent = utime + stime; proc_state_ptr->cpu_percent = (((double)(utime + stime) * 100) / ( now_time - pi->pi_start )) / ncpus; proc_state_ptr->nice = pi->pi_nice; /* determine comm & cmndline */ if( (pi->pi_flags & SKPROC) == SKPROC ) { if( pi->pi_pid == 0 ) { snprintf(comm, ARG_MAX, "kproc (swapper)"); snprintf(cmndline, ARG_MAX, "kproc (swapper)"); } else { snprintf(comm, ARG_MAX, "kproc (%s)", pi->pi_comm); snprintf(cmndline, ARG_MAX, "kproc (%s)", pi->pi_comm); } } else { snprintf(comm, ARG_MAX, "%s", pi->pi_comm); curproc_for_getargs.pi_pid = pi->pi_pid; if( getargs(&curproc_for_getargs, sizeof(curproc_for_getargs), cmndline, ARG_MAX) < 0 ) { snprintf(cmndline, ARG_MAX, "%s", pi->pi_comm); } else { int done = 0; /* replace NUL characters in command line with spaces */ char *c = cmndline; while( ! done ) { if( *c == '\0' ) { if( *(c+1) == '\0' ) { done = 1; } else { *c++ = ' '; } } else { ++c; } } } } if (sg_update_string(&proc_state_ptr->process_name, comm) < 0) { free(procs); return NULL; } if (sg_update_string(&proc_state_ptr->proctitle, cmndline) < 0) { free(procs); return NULL; } proc_idx++; } } while( fetched >= PROCS_TO_FETCH ); proc_state_size = proc_idx; free(procs); #endif #ifdef CYGWIN sg_set_error(SG_ERROR_UNSUPPORTED, "Cygwin"); return NULL; #endif #ifdef WIN32 /* FIXME The data needed for this is probably do able with the * "performance registry". Although using this appears to be a black * art and closely guarded secret. * This is not directly used in ihost, so not considered a priority */ sg_set_error(SG_ERROR_UNSUPPORTED, "Win32"); return NULL; #endif *entries = proc_state_size; return proc_state; } sg_process_count *sg_get_process_count() { static sg_process_count process_stat; #ifndef WIN32 sg_process_stats *ps; int ps_size, x; #else DWORD aProcesses[1024]; DWORD cbNeeded; #endif process_stat.sleeping = 0; process_stat.running = 0; process_stat.zombie = 0; process_stat.stopped = 0; process_stat.total = 0; #ifndef WIN32 ps = sg_get_process_stats(&ps_size); if (ps == NULL) { return NULL; } for(x = 0; x < ps_size; x++) { switch (ps->state) { case SG_PROCESS_STATE_RUNNING: process_stat.running++; break; case SG_PROCESS_STATE_SLEEPING: process_stat.sleeping++; break; case SG_PROCESS_STATE_STOPPED: process_stat.stopped++; break; case SG_PROCESS_STATE_ZOMBIE: process_stat.zombie++; break; default: /* currently no mapping for SG_PROCESS_STATE_UNKNOWN in * sg_process_count */ break; } ps++; } process_stat.total = ps_size; #else if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return NULL; process_stat.total = cbNeeded / sizeof(DWORD); #endif return &process_stat; } int sg_process_compare_name(const void *va, const void *vb) { const sg_process_stats *a = (sg_process_stats *)va; const sg_process_stats *b = (sg_process_stats *)vb; return strcmp(a->process_name, b->process_name); } int sg_process_compare_pid(const void *va, const void *vb) { const sg_process_stats *a = (sg_process_stats *)va; const sg_process_stats *b = (sg_process_stats *)vb; if (a->pid < b->pid) { return -1; } else if (a->pid == b->pid) { return 0; } else { return 1; } } int sg_process_compare_uid(const void *va, const void *vb) { const sg_process_stats *a = (sg_process_stats *)va; const sg_process_stats *b = (sg_process_stats *)vb; if (a->uid < b->uid) { return -1; } else if (a->uid == b->uid) { return 0; } else { return 1; } } int sg_process_compare_gid(const void *va, const void *vb) { const sg_process_stats *a = (sg_process_stats *)va; const sg_process_stats *b = (sg_process_stats *)vb; if (a->gid < b->gid) { return -1; } else if (a->gid == b->gid) { return 0; } else { return 1; } } int sg_process_compare_size(const void *va, const void *vb) { const sg_process_stats *a = (sg_process_stats *)va; const sg_process_stats *b = (sg_process_stats *)vb; if (a->proc_size < b->proc_size) { return -1; } else if (a->proc_size == b->proc_size) { return 0; } else { return 1; } } int sg_process_compare_res(const void *va, const void *vb) { const sg_process_stats *a = (sg_process_stats *)va; const sg_process_stats *b = (sg_process_stats *)vb; if (a->proc_resident < b->proc_resident) { return -1; } else if (a->proc_resident == b->proc_resident) { return 0; } else { return 1; } } int sg_process_compare_cpu(const void *va, const void *vb) { const sg_process_stats *a = (sg_process_stats *)va; const sg_process_stats *b = (sg_process_stats *)vb; if (a->cpu_percent < b->cpu_percent) { return -1; } else if (a->cpu_percent == b->cpu_percent) { return 0; } else { return 1; } } int sg_process_compare_time(const void *va, const void *vb) { const sg_process_stats *a = (sg_process_stats *)va; const sg_process_stats *b = (sg_process_stats *)vb; if (a->time_spent < b->time_spent) { return -1; } else if (a->time_spent == b->time_spent) { return 0; } else { return 1; } }
/* --------------------------------------------------------------------- */ int netsnmp_arch_swrun_container_load( netsnmp_container *container, u_int flags) { struct pst_status *proc_table; struct pst_dynamic pst_dyn; int nproc, i, rc; char *cp1, *cp2; netsnmp_swrun_entry *entry; pstat_getdynamic( &pst_dyn, sizeof(struct pst_dynamic), 1, 0); nproc = pst_dyn.psd_activeprocs; proc_table = (struct pst_status *) malloc(nproc*(sizeof(struct pst_status))); pstat_getproc(proc_table, sizeof(struct pst_status), nproc, 0); for ( i=0 ; i<nproc; i++ ) { entry = netsnmp_swrun_entry_create(proc_table[i].pst_pid); if (NULL == entry) continue; /* error already logged by function */ rc = CONTAINER_INSERT(container, entry); entry->hrSWRunName_len = snprintf(entry->hrSWRunName, sizeof(entry->hrSWRunName)-1, "%s", proc_table[i].pst_ucomm); /* * Split pst_cmd into two: * argv[0] is hrSWRunPath * argv[1..] is hrSWRunParameters */ for ( cp1 = proc_table[i].pst_cmd; ' ' == *cp1; cp1++ ) ; *cp1 = '\0'; /* End of argv[0] */ entry->hrSWRunPath_len = snprintf(entry->hrSWRunPath, sizeof(entry->hrSWRunPath)-1, "%s", proc_table[i].pst_cmd); entry->hrSWRunParameters_len = snprintf(entry->hrSWRunParameters, sizeof(entry->hrSWRunParameters)-1, "%s", cp1+1); *cp1 = ' '; /* Restore pst_cmd value */ entry->hrSWRunType = (PS_SYS & proc_table[i].pst_flag) ? 2 /* kernel process */ : 4 /* application */ ; switch (proc_table[i].pst_stat) { case PS_RUN: entry->hrSWRunStatus = HRSWRUNSTATUS_RUNNING; break; case PS_SLEEP: entry->hrSWRunStatus = HRSWRUNSTATUS_RUNNABLE; break; case PS_STOP: entry->hrSWRunStatus = HRSWRUNSTATUS_NOTRUNNABLE; break; case PS_IDLE: case PS_ZOMBIE: case PS_OTHER: default: entry->hrSWRunStatus = HRSWRUNSTATUS_INVALID; break; } entry->hrSWRunPerfCPU = proc_table[i].pst_cptickstotal; entry->hrSWRunPerfMem = proc_table[i].pst_rssize; entry->hrSWRunPerfMem *= getpagesize() / 1024; /* in kB */ /* XXX - Check this last calculation */ } free(proc_table); DEBUGMSGTL(("swrun:load:arch"," loaded %d entries\n", CONTAINER_SIZE(container))); return 0; }
int PROC_NUM(AGENT_REQUEST *request, AGENT_RESULT *result) { #define ZBX_BURST ((size_t)10) char *procname, *proccomm, *param; struct passwd *usrinfo; int proccount = 0, invalid_user = 0, zbx_proc_stat, i, count, idx = 0; struct pst_status pst[ZBX_BURST]; if (4 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } procname = get_rparam(request, 0); if (NULL != procname && '\0' == *procname) procname = NULL; param = get_rparam(request, 1); if (NULL != param && '\0' != *param) { errno = 0; if (NULL == (usrinfo = getpwnam(param))) { if (0 != errno) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain user information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } invalid_user = 1; } } else usrinfo = NULL; param = get_rparam(request, 2); if (NULL == param || '\0' == *param || 0 == strcmp(param, "all")) zbx_proc_stat = ZBX_PROC_STAT_ALL; else if (0 == strcmp(param, "run")) zbx_proc_stat = ZBX_PROC_STAT_RUN; else if (0 == strcmp(param, "sleep")) zbx_proc_stat = ZBX_PROC_STAT_SLEEP; else if (0 == strcmp(param, "zomb")) zbx_proc_stat = ZBX_PROC_STAT_ZOMB; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); return SYSINFO_RET_FAIL; } proccomm = get_rparam(request, 3); if (NULL != proccomm && '\0' == *proccomm) proccomm = NULL; if (1 == invalid_user) /* handle 0 for non-existent user after all parameters have been parsed and validated */ goto out; memset(pst, 0, sizeof(pst)); while (0 < (count = pstat_getproc(pst, sizeof(*pst), ZBX_BURST, idx))) { for (i = 0; i < count; i++) { if (NULL != procname && 0 != strcmp(pst[i].pst_ucomm, procname)) continue; if (NULL != usrinfo && usrinfo->pw_uid != pst[i].pst_uid) continue; if (NULL != proccomm && NULL == zbx_regexp_match(pst[i].pst_cmd, proccomm, NULL)) continue; if (FAIL == check_procstate(pst[i], zbx_proc_stat)) continue; proccount++; } idx = pst[count - 1].pst_idx + 1; memset(pst, 0, sizeof(pst)); } if (-1 == count) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain process information.")); return SYSINFO_RET_FAIL; } out: SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
oslProcessError SAL_CALL osl_getProcessInfo(oslProcess Process, oslProcessData Fields, oslProcessInfo* pInfo) { pid_t pid; if (Process == NULL) pid = getpid(); else pid = ((oslProcessImpl*)Process)->m_pid; if (! pInfo || (pInfo->Size != sizeof(oslProcessInfo))) return osl_Process_E_Unknown; pInfo->Fields = 0; if (Fields & osl_Process_IDENTIFIER) { pInfo->Ident = pid; pInfo->Fields |= osl_Process_IDENTIFIER; } if (Fields & osl_Process_EXITCODE) { if ((Process != NULL) && osl_checkCondition(((oslProcessImpl*)Process)->m_terminated)) { pInfo->Code = ((oslProcessImpl*)Process)->m_status; pInfo->Fields |= osl_Process_EXITCODE; } } if (Fields & (osl_Process_HEAPUSAGE | osl_Process_CPUTIMES)) { #if defined(SOLARIS) int fd; sal_Char name[PATH_MAX + 1]; snprintf(name, sizeof(name), "/proc/%u", pid); if ((fd = open(name, O_RDONLY)) >= 0) { prstatus_t prstatus; if (ioctl(fd, PIOCSTATUS, &prstatus) >= 0) { if (Fields & osl_Process_CPUTIMES) { pInfo->UserTime.Seconds = prstatus.pr_utime.tv_sec; pInfo->UserTime.Nanosec = prstatus.pr_utime.tv_nsec; pInfo->SystemTime.Seconds = prstatus.pr_stime.tv_sec; pInfo->SystemTime.Nanosec = prstatus.pr_stime.tv_nsec; pInfo->Fields |= osl_Process_CPUTIMES; } if (Fields & osl_Process_HEAPUSAGE) { pInfo->HeapUsage = prstatus.pr_brksize; pInfo->Fields |= osl_Process_HEAPUSAGE; } close(fd); return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown; } else close(fd); } #elif defined(HPUX) struct pst_status prstatus; if (pstat_getproc(&prstatus, sizeof(prstatus), (size_t)0, pid) == 1) { if (Fields & osl_Process_CPUTIMES) { pInfo->UserTime.Seconds = prstatus.pst_utime; pInfo->UserTime.Nanosec = 500000L; pInfo->SystemTime.Seconds = prstatus.pst_stime; pInfo->SystemTime.Nanosec = 500000L; pInfo->Fields |= osl_Process_CPUTIMES; } if (Fields & osl_Process_HEAPUSAGE) { pInfo->HeapUsage = prstatus.pst_vdsize*PAGESIZE; pInfo->Fields |= osl_Process_HEAPUSAGE; } return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown; } #elif defined(LINUX) if ( (Fields & osl_Process_CPUTIMES) || (Fields & osl_Process_HEAPUSAGE) ) { struct osl_procStat procstat; memset(&procstat,0,sizeof(procstat)); if ( (Fields & osl_Process_CPUTIMES) && osl_getProcStat(pid, &procstat) ) { /* * mfe: * We calculate only time of the process proper. * Threads are processes, we do not consider their time here! * (For this, cutime and cstime should be used, it seems not * to work in 2.0.36) */ long clktck; unsigned long hz; unsigned long userseconds; unsigned long systemseconds; clktck = sysconf(_SC_CLK_TCK); if (clktck < 0) { return osl_Process_E_Unknown; } hz = (unsigned long) clktck; userseconds = procstat.utime/hz; systemseconds = procstat.stime/hz; pInfo->UserTime.Seconds = userseconds; pInfo->UserTime.Nanosec = procstat.utime - (userseconds * hz); pInfo->SystemTime.Seconds = systemseconds; pInfo->SystemTime.Nanosec = procstat.stime - (systemseconds * hz); pInfo->Fields |= osl_Process_CPUTIMES; } if ( (Fields & osl_Process_HEAPUSAGE) && osl_getProcStatus(pid, &procstat) ) { /* * mfe: * vm_data (found in status) shows the size of the data segment * it a rough approximation of the core heap size */ pInfo->HeapUsage = procstat.vm_data*1024; pInfo->Fields |= osl_Process_HEAPUSAGE; } } return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown; #endif } return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown; }
Boolean ServerProcess::isCIMServerRunning(void) { FILE *pid_file; pid_t pid = 0; // open the file containing the CIMServer process ID pid_file = fopen(getPIDFileName(), "r"); if (!pid_file) { return false; } // get the pid from the file fscanf(pid_file, "%d\n", &pid); fclose(pid_file); if (pid == 0) { return false; } // // check to see if cimserver process is alive // #if defined(PEGASUS_OS_HPUX) struct pst_status pstru; int ret_code; ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid); if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, getProcessName())) == 0) { // // Check to see if this command process has the same pid as the // cimserver daemon process pid stored in the cimserver_start.conf // file. Since the command has the same name as the cimserver daemon // process, this could happen after a system reboot. If the pids are // the same, cimserver isn't really running. // Uint32 mypid = System::getPID(); if ((mypid != pid) && (parentPid != pid)) { // cimserver is running return true; } } #endif #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) if (get_proc(pid) != -1 ) { // cimserver is running return true; } #endif #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) return isProcRunning(pid); #endif #if defined(PEGASUS_OS_AIX) if (aixcimsrvrunning(pid, getProcessName())!=-1) return true; #endif return false; }
// HPUX should have this DWORD CTGetPidOfCmdLine( PCSTR programName, PCSTR programFilename, PCSTR cmdLine, uid_t owner, pid_t *pid, size_t *count ) { DWORD ceError = ERROR_NOT_SUPPORTED; size_t fillCount = 0; size_t foundCount = 0; struct stat findStat; struct pst_status mystatus; struct pst_status status[10]; int inBuffer; int i; if(count) { fillCount = *count; *count = 0; } else if(pid != NULL) fillCount = 1; if(programFilename != NULL) { while(stat(programFilename, &findStat) < 0) { if(errno == EINTR) continue; GCE(ceError = LwMapErrnoToLwError(errno)); } } //First get the process info for this process inBuffer = pstat_getproc(&mystatus, sizeof(mystatus), 0, getpid()); if(inBuffer != 1) GCE(ceError = LwMapErrnoToLwError(errno)); //Now look at all processes inBuffer = pstat_getproc(status, sizeof(status[0]), sizeof(status)/sizeof(status[0]), 0); if(inBuffer < 0) GCE(ceError = LwMapErrnoToLwError(errno)); while(inBuffer > 0) { for(i = 0; i < inBuffer; i++) { if(memcmp(&mystatus.pst_rdir, &status[i].pst_rdir, sizeof(mystatus.pst_rdir))) { /* This process has a different root directory (it is being run via a chroot). Let's not count this process as a match. */ continue; } if (owner != (uid_t)-1 && owner != status[i].pst_euid) { continue; } if (programName != NULL && strcmp(status[i].pst_ucomm, programName)) { continue; } if (cmdLine != NULL && strcmp(status[i].pst_cmd, cmdLine)) { continue; } if(programFilename != NULL && ( status[i].pst_text.psf_fileid != findStat.st_ino || status[i].pst_text.psf_fsid.psfs_id != findStat.st_dev || status[i].pst_text.psf_fsid.psfs_type != findStat.st_fstype )) { continue; } //This is a match if(foundCount < fillCount) pid[foundCount] = status[i].pst_pid; foundCount++; } //Continue looking at the process list where we left off inBuffer = pstat_getproc(status, sizeof(status[0]), sizeof(status)/sizeof(status[0]), status[inBuffer - 1].pst_idx + 1); if(inBuffer < 0) GCE(ceError = LwMapErrnoToLwError(errno)); } ceError = ERROR_SUCCESS; if(count) *count = foundCount; else if(!ceError && foundCount == 0) ceError = ERROR_PROC_NOT_FOUND; cleanup: return ceError; }