1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1989-2011 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <glenn.s.fowler@gmail.com> * 18 * * 19 ***********************************************************************/ 20 #pragma prototyped 21 /* 22 * Glenn Fowler 23 * AT&T Research 24 * 25 * process status stream PSS_METHOD_getprocs implementation 26 */ 27 28 #include "psslib.h" 29 30 #if PSS_METHOD != PSS_METHOD_getprocs 31 32 NoN(pss_getprocs) 33 34 #else 35 36 #include <procinfo.h> 37 #include <sys/proc.h> 38 39 #if _mem_pi_pri_procsinfo64 40 #define procsinfo procsinfo64 41 #else 42 #undef PSS_pri 43 #define PSS_pri 0 44 #endif 45 46 #undef PSS_gid 47 #define PSS_gid 0 48 #undef PSS_npid 49 #define PSS_npid 0 50 #undef PSS_proc 51 #define PSS_proc 0 52 #undef PSS_sched 53 #define PSS_sched 0 54 #undef PSS_tgrp 55 #define PSS_tgrp 0 56 57 typedef struct State_s 58 { 59 struct procsinfo entry[64]; 60 struct procsinfo* pr; 61 int last; 62 int index; 63 int count; 64 } State_t; 65 66 static int 67 getprocs_init(Pss_t* pss) 68 { 69 register State_t* state; 70 71 if (!(state = vmnewof(pss->vm, 0, State_t, 1, 0))) 72 { 73 if (pss->disc->errorf) 74 (*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space"); 75 return -1; 76 } 77 pss->data = state; 78 return 1; 79 } 80 81 static int 82 getprocs_read(Pss_t* pss, Pss_id_t pid) 83 { 84 register State_t* state = (State_t*)pss->data; 85 86 if (pid) 87 { 88 pss->pid = pid; 89 state->index = 0; 90 if ((state->count = getprocs(state->entry, sizeof(state->entry[0]), NiL, 0, &pss->pid, 1)) != 1) 91 return -1; 92 state->last = 0; 93 } 94 else 95 while (state->index >= state->count) 96 { 97 if (state->last) 98 return 0; 99 state->index = 0; 100 state->count = getprocs(state->entry, sizeof(state->entry[0]), NiL, 0, &pss->pid, elementsof(state->entry)); 101 if (state->count < elementsof(state->entry)) 102 { 103 state->last = 1; 104 if (state->count < 0) 105 return -1; 106 if (!state->count) 107 return 0; 108 } 109 if (!state->entry[0].pi_pid) 110 state->index++; 111 } 112 state->pr = state->entry + state->index++; 113 return 1; 114 } 115 116 static int 117 getprocs_part(register Pss_t* pss, register Pssent_t* pe) 118 { 119 register State_t* state = (State_t*)pss->data; 120 register struct procsinfo* pr; 121 122 pr = state->pr; 123 pe->pid = state->pr->pi_pid; 124 pe->pgrp = pr->pi_pgrp; 125 pe->sid = pr->pi_sid; 126 pe->tty = pr->pi_ttyp ? pr->pi_ttyd : PSS_NODEV; 127 pe->uid = pr->pi_uid; 128 switch (pr->pi_state) 129 { 130 case SACTIVE: 131 pe->state = 'R'; 132 break; 133 case SIDL: 134 pe->state = 'I'; 135 break; 136 case SSTOP: 137 pe->state = 'T'; 138 break; 139 case SSWAP: 140 pe->state = 'W'; 141 break; 142 case SZOMB: 143 pe->state = 'Z'; 144 break; 145 default: 146 pe->state = 'O'; 147 break; 148 } 149 return 1; 150 } 151 152 static int 153 getprocs_full(register Pss_t* pss, register Pssent_t* pe) 154 { 155 register State_t* state = (State_t*)pss->data; 156 register struct procsinfo* pr = state->pr; 157 unsigned long fields = pss->disc->fields & pss->meth->fields; 158 char* s; 159 int i; 160 161 if (pe->state != PSS_ZOMBIE) 162 { 163 if (fields & PSS_args) 164 { 165 s = pr->pi_comm; 166 if (s[0] == '(' && s[i = strlen(s) - 1] == ')') 167 { 168 s[i] = 0; 169 s++; 170 } 171 pe->args = s; 172 } 173 if (fields & PSS_command) 174 { 175 s = pr->pi_comm; 176 if (s[0] == '(' && s[i = strlen(s) - 1] == ')') 177 { 178 s[i] = 0; 179 s++; 180 } 181 pe->command = s; 182 } 183 } 184 pe->addr = (void*)pr->pi_adspace; 185 pe->flags = pr->pi_flags; 186 pe->nice = pr->pi_nice; 187 pe->ppid = pr->pi_ppid; 188 #if PSS_pri 189 pe->pri = pr->pi_pri; 190 #endif 191 pe->refcount = pr->pi_thcount; 192 pe->rss = pr->pi_drss + pr->pi_trss; 193 pe->size = pr->pi_size; 194 pe->start = pr->pi_start; 195 pe->time = pr->pi_ru.ru_utime.tv_sec + pr->pi_ru.ru_stime.tv_sec; 196 return 1; 197 } 198 199 static Pssmeth_t getprocs_method = 200 { 201 "getprocs", 202 "[-version?@(#)$Id: pss getprocs (AT&T Research) 2004-02-29 $\n]" 203 "[-author?Glenn Fowler <gsf@research.att.com>]", 204 PSS_all, 205 getprocs_init, 206 getprocs_read, 207 getprocs_part, 208 getprocs_full, 209 0, 210 0, 211 0, 212 0 213 }; 214 215 Pssmeth_t* _pss_method = &getprocs_method; 216 217 #endif 218