void bless_procs(struct procsinfo64 *procs, int count) { int index; char cmndline[ARG_MAX]; char comm[ARG_MAX]; char pctmem[PCT_LENGTH]; char pctcpu[PCT_LENGTH]; char state[STATE_LENGTH]; char *c = NULL; struct procsinfo64 *curproc = NULL; struct procsinfo curproc_for_getargs; int zombie; int done; long utime, stime, cutime, cstime; /* initialize */ Zero(&curproc_for_getargs, 1, struct procsinfo); for( index = 0, curproc = procs; index < count; index++, curproc = procs+index ) { /* reset char fields */ memset(cmndline, 0, ARG_MAX); memset(comm, 0, ARG_MAX); memset(pctmem, 0, PCT_LENGTH); memset(pctcpu, 0, PCT_LENGTH); memset(state, 0, STATE_LENGTH); /* skip procs with a state of NONE */ if( curproc->pi_state == SNONE ) { continue; } /* copy the format into something we can use */ strcpy(format, Defaultformat); /* presume we are not a zombie */ zombie = 0; /* set a descriptive name for the process state */ switch( curproc->pi_state ) { case SSLEEP: strcpy(state, SLEEP); break; case SRUN: strcpy(state, RUN); break; case SIDL: strcpy(state, IDLE); break; case SZOMB: strcpy(state, ZOMBIE); zombie = 1; break; case SSTOP: strcpy(state, STOP); break; case SACTIVE: strcpy(state, ACTIVE); break; default: format[F_STAT] = 'S'; break; } /* calc utime, stime, cutime, cstime */ if( zombie ) { utime = curproc->pi_utime; stime = curproc->pi_stime; } else { utime = TVALN_TO_SEC(curproc->pi_ru.ru_utime); stime = TVALN_TO_SEC(curproc->pi_ru.ru_stime); cutime = TVALN_TO_SEC(curproc->pi_cru.ru_utime); cstime = TVALN_TO_SEC(curproc->pi_cru.ru_stime); } /* calc pctcpu */ sprintf(pctcpu, "%3.2f", ((utime + stime) * 100 / ( now_time - curproc->pi_start )) / ncpus ); /* calc pctmem */ if( memory == 0 ) { format[F_PCTMEM] = 'S'; } else { sprintf(pctmem, "%3.2f", (curproc->pi_drss + curproc->pi_trss) * pagesize * 100 / (float)memory); } /* determine comm & cmndline */ if( (curproc->pi_flags & SKPROC) == SKPROC ) { if( curproc->pi_pid == 0 ) { snprintf(comm, ARG_MAX, "kproc (swapper)"); snprintf(cmndline, ARG_MAX, "kproc (swapper)"); } else { snprintf(comm, ARG_MAX, "kproc (%s)", curproc->pi_comm); snprintf(cmndline, ARG_MAX, "kproc (%s)", curproc->pi_comm); } } else { snprintf(comm, ARG_MAX, "%s", curproc->pi_comm); curproc_for_getargs.pi_pid = curproc->pi_pid; if( getargs(&curproc_for_getargs, sizeof(struct procsinfo), cmndline, ARG_MAX) < 0 ) { snprintf(cmndline, ARG_MAX, "%s", curproc->pi_comm); } else { /* replace NUL characters in command line with spaces */ c = cmndline; done = 0; while( ! done ) { if( *c == '\0' ) { if( *(c+1) == '\0' ) { done = 1; } else { *c++ = ' '; } } else { c++; } } } } /* sanity check: bless_into_procs doesn't like negative ints */ if( curproc->pi_cred.cr_uid == -1 ) { format[F_EUID] = 'I'; curproc->pi_cred.cr_uid = 0; } if( curproc->pi_ttyd == -1 ) { format[F_TTYNUM] = 'I'; curproc->pi_ttyd = 0; } if( curproc->pi_ttympx == -1 ) { format[F_TTYMPX] = 'I'; curproc->pi_ttympx = 0; } /* give it to Perl */ bless_into_proc(format, Fields, curproc->pi_pid, /* pid */ curproc->pi_ppid, /* ppid */ curproc->pi_sid, /* sess */ curproc->pi_pgrp, /* pgrp */ curproc->pi_uid, /* uid */ curproc->pi_suid, /* suid */ curproc->pi_cred.cr_luid, /* luid */ curproc->pi_cred.cr_uid, /* euid */ curproc->pi_cred.cr_rgid, /* gid */ curproc->pi_cred.cr_gid, /* egid */ curproc->pi_pri, /* priority */ curproc->pi_nice, /* nice */ curproc->pi_thcount, /* thcount */ state, curproc->pi_flags, /* flags */ curproc->pi_flags2, /* flags2 */ curproc->pi_adspace, /* adspace */ curproc->pi_majflt, /* majflt */ curproc->pi_minflt, /* minflt */ (long)(utime * 100), /* utime */ (long)(stime * 100), /* stime */ (long)(cutime * 100), /* cutime */ (long)(cstime * 100), /* cstime */ curproc->pi_start, /* start */ curproc->pi_size, /* size */ curproc->pi_tsize, /* tsize */ curproc->pi_ttyp, /* ttyp */ curproc->pi_ttyd, /* ttynum */ curproc->pi_ttympx, /* ttympx */ curproc->pi_drss, /* drss */ curproc->pi_trss, /* trss */ curproc->pi_dvm, /* dvm */ pctmem, /* pctmem */ pctcpu, /* pctcpu */ comm, /* comm */ cmndline /* cmndline */ ); } }
void OS_get_table() { int i, proc_nb; struct procinfo pr_buff[MAX_PROCS]; struct userinfo uinfo; char format[F_FLAST + 1]; char wchan[15], pctcpu[7], pctmem[7], state[10]; char Args[MAXARGLN+1], Arglist[MAXARGLN+1], Comm[MAXARGLN+1]; int argcount; struct timeval now_tval; double utime, stime, cutime, cstime, now; strcpy(format, Fullformat); proc_nb = getproc(pr_buff, MAX_PROCS, sizeof(struct procinfo)); gettimeofday(&now_tval, (void *)NULL); now = (double)now_tval.tv_sec + (double) now_tval.tv_usec / 1000000.0; for(i=0; i<proc_nb; i++) { if ( pr_buff[i].pi_wchan != NULL ) { sprintf(wchan, "%p", pr_buff[i].pi_wchan); } if ( pr_buff[i].pi_stat == SNONE ) { continue; } switch (pr_buff[i].pi_stat){ case SSLEEP : strcpy(state, SLEEP); break; case SRUN : strcpy(state, RUN); break; case SIDL : strcpy(state, IDLE); break; case SZOMB : strcpy(state, ZOMBIE); break; case SSTOP : strcpy(state, STOP); break; case SACTIVE : strcpy(state, ACTIVE); break; default: format[F_STAT] = 'S'; } if ( state == ZOMBIE || getuser(&pr_buff[i], sizeof(struct procinfo), &uinfo, sizeof(struct userinfo) ) < 0 ) { bless_into_proc( Zombformat, ZombFields, pr_buff[i].pi_pid, pr_buff[i].pi_ppid, pr_buff[i].pi_sid, pr_buff[i].pi_pgrp, pr_buff[i].pi_uid, pr_buff[i].pi_suid, pr_buff[i].pi_pri, pr_buff[i].pi_nice, pr_buff[i].pi_cpu, /* pr_buff[i].pi_stat, */ state, pr_buff[i].pi_flag, wchan, pr_buff[i].pi_wtype, pr_buff[i].pi_adspace, pr_buff[i].pi_majflt, pr_buff[i].pi_minflt, pr_buff[i].pi_utime, pr_buff[i].pi_stime, pr_buff[i].pi_size * PageSize ); continue; } /* * Command line args processing * */ Args[0] = '\0'; if ( pr_buff[i].pi_flag & SKPROC ) { if ( pr_buff[i].pi_pid == 0 ) { strcpy(Args, "kproc (swapper)"); strcpy(Comm, "kproc (swapper)"); } else { sprintf(Args, "kproc (%s)", uinfo.ui_comm); sprintf(Comm, "kproc (%s)", uinfo.ui_comm); } } else { strncpy(Comm, uinfo.ui_comm, MAXARGLN); Comm[MAXARGLN] = '\0'; if (getargs(&pr_buff[i], sizeof(struct procinfo), Arglist, MAXARGLN) < 0) { sprintf(Args, "%s", uinfo.ui_comm); } else { /* Returns a succession of strings seperated by a null characters, 2 nulls for the end (see getargs info/man page) */ argcount = -1; while (++argcount < MAXARGLN) { /* Copy everything but replace the end of the arg with a space */ if (Arglist[argcount] != '\0') { Args[argcount] = Arglist[argcount]; } else { /* Is this the last arg, then hop out of the loop */ if (Arglist[argcount+1] == '\0') { /* Terminate the arguments */ Args[argcount] = '\0'; break; } /* Seperate arguments with a space */ Args[argcount] = ' '; } } } } /* * Convert time values into seconds * */ utime = uinfo.ui_ru.ru_utime.tv_sec + (double) uinfo.ui_ru.ru_utime.tv_usec / 1000000.0; stime = uinfo.ui_ru.ru_stime.tv_sec + (double) uinfo.ui_ru.ru_stime.tv_usec / 1000000.0; cutime = uinfo.ui_cru.ru_utime.tv_sec + (double) uinfo.ui_cru.ru_utime.tv_usec / 1000000.0; cstime = uinfo.ui_cru.ru_stime.tv_sec + (double) uinfo.ui_cru.ru_stime.tv_usec / 1000000.0; /* * percentage calculation * */ pctcpu[0] = pctmem[0]= '\0'; /* compute %CPU in SMP environment */ sprintf( pctcpu, "%3.2f", ((utime + stime ) * 100 / ( now - uinfo.ui_start )) / ProcessNumber ); if ( Sysmem == 0 ) { format[F_PRM] = 'S'; } else { sprintf( pctmem, "%3.2f", (uinfo.ui_drss + uinfo.ui_trss) * PageSize * 100 / (float)Sysmem ); } /* * Give it all to Perl * (we convert time values to hundredth of a second * to keep in sync with the Linux version ) */ bless_into_proc( format, FullFields, pr_buff[i].pi_pid, pr_buff[i].pi_ppid, pr_buff[i].pi_sid, pr_buff[i].pi_pgrp, pr_buff[i].pi_uid, pr_buff[i].pi_suid, pr_buff[i].pi_pri, pr_buff[i].pi_nice, /* pr_buff[i].pi_cpu, */ pctcpu, /* pr_buff[i].pi_stat, */ state, pr_buff[i].pi_flag, wchan, pr_buff[i].pi_wtype, pr_buff[i].pi_adspace, pr_buff[i].pi_majflt, pr_buff[i].pi_minflt, ((pr_buff[i].pi_size * PageSize) - uinfo.ui_tsize)/1024, uinfo.ui_luid, uinfo.ui_uid, uinfo.ui_gid, uinfo.ui_start, (long) (utime * 100), (long) (stime * 100), (long) (cutime * 100), (long) (cstime * 100), uinfo.ui_tsize/1024, uinfo.ui_ttyp, uinfo.ui_ttyd, uinfo.ui_ttympx, ((uinfo.ui_drss + uinfo.ui_trss) * PageSize)/1024, (uinfo.ui_trss * PageSize)/1024, uinfo.ui_dvm, /* uinfo.ui_prm,*/ pctmem, Comm, Args ); } }
void OS_get_table() { /* dir walker storage */ DIR *dir; struct dirent *dir_ent, *dir_result; /* all our storage is going to be here */ struct obstack mem_pool; /* container for scaped process values */ struct procstat *prs; /* string containing our local copy of format_str, elements will be * lower cased if we are able to figure them out */ char *format_str; /* initlize a small memory pool for this function */ obstack_init(&mem_pool); /* put the dirent on the obstack, since it's rather large */ dir_ent = obstack_alloc(&mem_pool, sizeof(struct dirent)); if ((dir = opendir("/proc")) == NULL) return; /* Iterate through all the process entries (numeric) under /proc */ while(readdir_r(dir, dir_ent, &dir_result) == 0 && dir_result) { /* Only look at this file if it's a proc id; that is, all numbers */ if(!is_pid(dir_result->d_name)) continue; /* allocate container for storing process values */ prs = obstack_alloc(&mem_pool, sizeof(struct procstat)); bzero(prs, sizeof(struct procstat)); /* intilize the format string */ obstack_printf(&mem_pool, get_string(STR_DEFAULT_FORMAT)); obstack_1grow(&mem_pool, '\0'); format_str = (char *) obstack_finish(&mem_pool); /* get process' uid/guid */ get_user_info(dir_result->d_name, format_str, prs, &mem_pool); /* scrape /proc/${pid}/stat */ if (get_proc_stat(dir_result->d_name, format_str, prs, &mem_pool) == false) { /* did the pid directory go away mid flight? */ if (pid_exists(dir_result->d_name, &mem_pool) == false) continue; } /* correct values (times) found in /proc/${pid}/stat */ fixup_stat_values(format_str, prs); /* get process' cmndline */ get_proc_cmndline(dir_result->d_name, format_str, prs, &mem_pool); /* get process' cwd & exec values from the symblink */ eval_link(dir_result->d_name, "cwd", F_CWD, &prs->cwd, format_str, &mem_pool); eval_link(dir_result->d_name, "exe", F_EXEC, &prs->exec, format_str, &mem_pool); /* scapre from /proc/{$pid}/status */ get_proc_status(dir_result->d_name, format_str, prs, &mem_pool); /* calculate precent cpu & mem values */ calc_prec(format_str, prs, &mem_pool); /* Go ahead and bless into a perl object */ bless_into_proc(format_str, field_names, prs->uid, prs->gid, prs->pid, prs->comm, prs->ppid, prs->pgrp, prs->sid, prs->tty, prs->flags, prs->minflt, prs->cminflt, prs->majflt, prs->cmajflt, prs->utime, prs->stime, prs->cutime, prs->cstime, prs->priority, prs->start_time, prs->vsize, prs->rss, prs->wchan, prs->time, prs->ctime, prs->state, prs->euid, prs->suid, prs->fuid, prs->egid, prs->sgid, prs->fgid, prs->pctcpu, prs->pctmem, prs->cmndline, prs->exec, prs->cwd ); /* we want a new prs, for the next itteration */ obstack_free(&mem_pool, prs); } closedir(dir); /* free all our tempoary memory */ obstack_free(&mem_pool, NULL); }
void OS_get_table() { kvm_t *kd; char errbuf[_POSIX2_LINE_MAX]; struct kinfo_proc *procs; /* array of processes */ int count; /* returns number of processes */ int i, j; int seconds, minutes, secleft; /* for time[20] */ int milsec, shortmsec; /* for miliseconds of time[20] */ int ttynum; long start; char *ttydev; static time_t now; /* for started[20] */ struct tm *tp; /* for month/day/hour/min/AM/PM fields of started[20] */ int SECSPERHOUR = 3600; int SECSPERDAY = 24 * 3600; pid_t sesid; int length; char cmndline[MAXARGLN+1]; char ** argv; /* for bless_into_proc */ static char format[F_LASTFIELD + 1]; /* variables to hold some values for bless_into_proc */ char state[20]; char cputime[20]; char started[20]; char session[20]; char shortsess[20]; /* Open the kvm interface, get a descriptor */ if ((kd = kvm_open(NULL, NULL, NULL, 0, errbuf)) == NULL) { /* fprintf(stderr, "kvm_open: %s\n", errbuf); */ ppt_croak("kvm_open: ", errbuf); } /* Get the list of processes. */ if ((procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, &count)) == NULL) { kvm_close(kd); /* fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(kd)); */ ppt_croak("kvm_getprocs: ", kvm_geterr(kd)); } /* Iterate through the processes in kinfo_proc, sending proc info */ /* to bless_into_proc for each proc */ for (i=0; i < count; i++) { static struct pstats ps; static struct session seslead; strcpy(format, Defaultformat); /* get ttydev */ ttynum=procs[i].kp_eproc.e_tdev; ttydev=devname(ttynum, S_IFCHR); if (ttydev == NULL) ttydev = "??"; /* get the state of processes */ switch (procs[i].kp_proc.p_stat) { case SIDL: strcpy(state, IDLE); break; case SRUN: strcpy(state, RUN); break; case SSLEEP: strcpy(state, SLEEP); break; case SSTOP: strcpy(state, STOP); break; case SZOMB: strcpy(state, ZOMBIE); break; default: strcpy(state, UNKNOWN); break; } /* get the cpu time of processes */ seconds=procs[i].kp_proc.p_rtime.tv_sec; milsec=procs[i].kp_proc.p_rtime.tv_usec; shortmsec=roundit(milsec); if (seconds < 60) { if (seconds < 10) sprintf(cputime, "0:0%d.%d", seconds, shortmsec); else sprintf(cputime, "0:%d.%d", seconds, shortmsec); } else { minutes=seconds/60; secleft=seconds-(minutes * 60); if (secleft < 10) sprintf(cputime, "%d:0%d.%d", minutes, secleft, shortmsec); else sprintf(cputime, "%d:%d.%d", minutes, secleft, shortmsec); } /* get the start time of process (when started) */ /* fill the pstats struct using kvm_read */ if (kvm_read(kd, (u_long)procs[i].kp_proc.p_stats, (char *)&ps, sizeof(ps)) == sizeof(ps)) { start=ps.p_start.tv_sec; tp=localtime(&start); if (!now) (void)time(&now); if (now - ps.p_start.tv_sec < 24 * SECSPERHOUR) { static char fmt[] = __CONCAT("%l:%", "M%p"); (void)strftime(started, sizeof(started) - 1, fmt, tp); } else if (now - ps.p_start.tv_sec < 7 * SECSPERDAY) { static char fmt[] = __CONCAT("%a%", "I%p"); (void)strftime(started, sizeof(started) - 1, fmt, tp); } else (void)strftime(started, sizeof(started) - 1, "%e%b%y", tp); } /* get the session ID (ie: session pointer ID) */ sprintf(session, "%x", (u_long)procs[i].kp_eproc.e_sess); length=strlen(session); for (j=0; j < length; j++) { if (session[1] == '1') shortsess[j]=session[j+1]; else shortsess[j]=session[j+2]; } /* fill the session leader and proc struct using kvm_read */ if (kvm_read(kd, (u_long)procs[i].kp_eproc.e_sess, (char *)&seslead, sizeof(seslead)) == sizeof(seslead)) { static struct proc leader; if (kvm_read(kd, (u_long)seslead.s_leader, (char *)&leader, sizeof(leader)) == sizeof(leader)) { sesid=leader.p_pid; } } /* retrieve the arguments */ cmndline[0] = '\0'; argv = kvm_getargv(kd, (const struct kinfo_proc *) &(procs[i]) , 0); if (argv) { int j = 0; while (argv[j] && strlen(cmndline) <= MAXARGLN) { strcat(cmndline, argv[j]); strcat(cmndline, " "); j++; } } /* access everything else directly from the kernel, send it */ /* into bless_into_proc */ bless_into_proc( format, Fields, procs[i].kp_eproc.e_pcred.p_ruid, procs[i].kp_eproc.e_pcred.p_rgid, procs[i].kp_proc.p_pid, procs[i].kp_eproc.e_ppid, procs[i].kp_eproc.e_pgid, procs[i].kp_proc.p_priority - PZERO, shortsess, sesid, cputime, procs[i].kp_eproc.e_wmesg, procs[i].kp_proc.p_comm, state, started, ttydev, ttynum, cmndline ); } if (kd) { kvm_close(kd); } }
void OS_get_table() { kvm_t *kd; char errbuf[_POSIX2_LINE_MAX]; struct kinfo_proc *procs; int count; int i, argcount; int ttynum; long start; char *ttydev; char cmndline[ARG_MAX+1]; char **pargv; /* for bless_into_proc */ static char format[F_LASTFIELD + 2]; char state[20]; /* open the kvm interface */ if ((kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL) { ppt_croak("kvm_open: %s", errbuf); } /* get processes */ if ((procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(*procs), &count)) == NULL) { kvm_close(kd); ppt_croak("kvm_getprocs: %s", kvm_geterr(kd)); } /* bless_into_proc each process's information */ for (i=0; i < count; i++) { STRLCPY(1,format,Defaultformat); /* get ttydev */ ttynum=procs[i].p_tdev; ttydev=devname(ttynum, S_IFCHR); if (ttydev == NULL) ttydev = "??"; /* process state */ switch (procs[i].p_stat) { case SIDL: STRLCPY(2,state,"IDLE"); break; case SRUN: STRLCPY(3,state,"RUN"); break; case SSLEEP: STRLCPY(4,state,"SLEEP"); break; case SSTOP: STRLCPY(5,state,"STOP"); break; case SZOMB: STRLCPY(6,state,"ZOMBIE"); break; default: STRLCPY(7,state,"UNKNOWN"); break; } /* arguments */ cmndline[0] = '\0'; pargv = kvm_getargv(kd, (const struct kinfo_proc *) &(procs[i]), 0); if (pargv) { argcount = 0; while (pargv[argcount] && strlen(cmndline)+strlen(pargv[argcount])+1 <= ARG_MAX) { STRLCAT(1,cmndline,pargv[argcount]); if (pargv[argcount+1]) { STRLCAT(2,cmndline," "); } argcount++; } } /* everything else is straightforward, bless the lot */ bless_into_proc( format, Fields, ttynum, procs[i].p_ruid, procs[i].p_rgid, procs[i].p_uid, procs[i].p_gid, procs[i].p_pid, procs[i].p_ppid, procs[i].p__pgid, procs[i].p_sid, procs[i].p_rtime_sec, procs[i].p_uutime_sec, procs[i].p_ustime_sec, procs[i].p_ustart_sec, procs[i].p_comm, state, ttydev, cmndline ); } if (kd) { kvm_close(kd); } }
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; } }