Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/std/pss-ps.c
1808 views
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 <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* process status stream PSS_METHOD_ps implementation
26
*/
27
28
#include "psslib.h"
29
30
#if !defined(PSS_ps) || !defined(PSS_pso)
31
32
Pssmeth_t* _pss_ps = 0;
33
34
#else
35
36
#include <tm.h>
37
38
#define PSS_default (PSS_pgrp|PSS_pid|PSS_ppid|PSS_sid|PSS_state|PSS_tgrp|PSS_tty|PSS_uid)
39
40
typedef struct State_s
41
{
42
Sfio_t* ps;
43
unsigned long fields;
44
unsigned long now;
45
int scan;
46
int debug;
47
} State_t;
48
49
typedef struct Pso_s
50
{
51
unsigned long field;
52
const char* name;
53
} Pso_t;
54
55
static Pso_t pso[] =
56
{
57
PSS_pso
58
};
59
60
static int
61
ps_init(Pss_t* pss)
62
{
63
register State_t* state;
64
register Pso_t* po;
65
register unsigned long fields;
66
char* s;
67
68
if (!(state = vmnewof(pss->vm, 0, State_t, 1, 0)))
69
{
70
if (pss->disc->errorf)
71
(*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space");
72
return -1;
73
}
74
state->now = (unsigned long)time(NiL) + 60;
75
if ((s = getenv("_AST_PSS_ps")) && *s == 'd')
76
state->debug = 1;
77
fields = 0;
78
for (po = pso; po->field; po++)
79
fields |= po->field;
80
pss->meth->fields = state->fields = fields;
81
pss->data = state;
82
return 1;
83
}
84
85
static int
86
ps_done(Pss_t* pss)
87
{
88
register State_t* state = (State_t*)pss->data;
89
90
if (state->ps)
91
sfclose(state->ps);
92
return 1;
93
}
94
95
static int
96
ps_read(Pss_t* pss, Pss_id_t pid)
97
{
98
register State_t* state = (State_t*)pss->data;
99
register Pso_t* po;
100
register char* s;
101
register char* e;
102
register unsigned long fields;
103
int sep;
104
105
if (pid || !state->scan)
106
{
107
if (state->ps)
108
{
109
sfclose(state->ps);
110
state->ps = 0;
111
}
112
s = pss->buf;
113
e = s + sizeof(pss->buf);
114
s += sfsprintf(s, e - s, "%s", PSS_ps);
115
if (!pid)
116
{
117
if (pss->disc->flags & (PSS_ALL|PSS_UNMATCHED))
118
s += sfsprintf(s, e - s, " %s", PSS_ps_every);
119
else
120
switch (pss->disc->flags & (PSS_ATTACHED|PSS_DETACHED|PSS_LEADER))
121
{
122
case PSS_ATTACHED|PSS_DETACHED|PSS_LEADER:
123
s += sfsprintf(s, e - s, " %s", PSS_ps_every);
124
break;
125
case PSS_ATTACHED|PSS_DETACHED:
126
s += sfsprintf(s, e - s, " %s", PSS_ps_detached);
127
break;
128
case PSS_DETACHED|PSS_LEADER:
129
s += sfsprintf(s, e - s, " %s", PSS_ps_noleader);
130
break;
131
case PSS_ATTACHED|PSS_LEADER:
132
case PSS_ATTACHED:
133
s += sfsprintf(s, e - s, " %s", PSS_ps_all);
134
break;
135
}
136
}
137
s += sfsprintf(s, e - s, " -o");
138
fields = pss->disc->fields|PSS_default;
139
sep = ' ';
140
for (po = pso; po->field; po++)
141
if (po->field & fields)
142
{
143
s += sfsprintf(s, e - s, "%c%s", sep, po->name);
144
sep = ',';
145
}
146
if (pid)
147
{
148
state->scan = 0;
149
s += sfsprintf(s, e - s, " -p %lu", (unsigned long)pid);
150
}
151
else
152
state->scan = 1;
153
if ((pss->disc->flags & PSS_VERBOSE) && pss->disc->errorf)
154
(*pss->disc->errorf)(pss, pss->disc, 0, "%s", pss->buf);
155
if (!(state->ps = sfpopen(NiL, pss->buf, "r")) || !sfgetr(state->ps, '\n', 0))
156
return -1;
157
}
158
return 1;
159
}
160
161
static unsigned long
162
number(char* s, char** p, int base)
163
{
164
unsigned long n;
165
char* e;
166
167
for (;;)
168
{
169
n = strtoul(s, &e, base);
170
if (*e && !isspace(*e))
171
switch (base)
172
{
173
case 8:
174
if (*e == '8' || *e == '9')
175
{
176
base = 10;
177
continue;
178
}
179
/*FALLTHROUGH*/
180
case 10:
181
if (isxdigit(*e))
182
{
183
base = 16;
184
continue;
185
}
186
break;
187
}
188
break;
189
}
190
while (*e && !isspace(*e))
191
e++;
192
*p = e;
193
return n;
194
}
195
196
static int
197
ps_part(register Pss_t* pss, register Pssent_t* pe)
198
{
199
State_t* state = (State_t*)pss->data;
200
register Pso_t* po;
201
register unsigned long fields;
202
register char* s;
203
char* e;
204
char* t;
205
int c;
206
207
if (!(s = sfgetr(state->ps, '\n', 1)))
208
return -1;
209
memset(pe, sizeof(*pe), 0);
210
fields = pss->disc->fields|PSS_default;
211
for (po = pso; po->field; po++)
212
if (po->field & fields)
213
{
214
while (isspace(*s))
215
s++;
216
if (!*s)
217
break;
218
if (state->debug && pss->disc->errorf)
219
(*pss->disc->errorf)(pss, pss->disc, 2, "%s: %s", po->name, s);
220
switch (po->field)
221
{
222
case PSS_addr:
223
pe->addr = (void*)number(s, &e, 16);
224
break;
225
case PSS_args:
226
pe->args = e = s;
227
return 1;
228
case PSS_sched:
229
pe->sched = e = s;
230
break;
231
case PSS_command:
232
pe->command = (e = strrchr(s, '/')) ? (e + 1) : s;
233
e = s;
234
break;
235
case PSS_cpu:
236
pe->cpu = number(s, &e, 10);
237
break;
238
case PSS_flags:
239
pe->flags = number(s, &e, 8);
240
break;
241
case PSS_gid:
242
for (e = s; *e; e++)
243
if (isspace(*e))
244
{
245
*e++ = 0;
246
break;
247
}
248
pe->gid = strgid(s);
249
break;
250
case PSS_job:
251
pe->job = number(s, &e, 10);
252
break;
253
case PSS_nice:
254
pe->nice = number(s, &e, 10);
255
break;
256
case PSS_npid:
257
pe->npid = number(s, &e, 10);
258
break;
259
case PSS_pgrp:
260
pe->pgrp = number(s, &e, 10);
261
break;
262
case PSS_pid:
263
pe->pid = number(s, &e, 10);
264
break;
265
case PSS_ppid:
266
pe->ppid = number(s, &e, 10);
267
break;
268
case PSS_pri:
269
pe->pri = number(s, &e, 10);
270
break;
271
case PSS_proc:
272
pe->proc = number(s, &e, 10);
273
break;
274
case PSS_refcount:
275
pe->refcount = number(s, &e, 10);
276
break;
277
case PSS_rss:
278
pe->rss = number(s, &e, 10);
279
break;
280
case PSS_sid:
281
pe->sid = number(s, &e, 10);
282
break;
283
case PSS_size:
284
pe->size = number(s, &e, 10);
285
break;
286
case PSS_start:
287
c = 0;
288
for (t = s; *s; s++)
289
if (*s == '_' || isalpha(*s) && isdigit(*(s + 1)) || isdigit(*s) && isalpha(*(s + 1)))
290
c = 1;
291
else if (isspace(*s) && (c || !isdigit(*(s + 1))))
292
break;
293
c = *s;
294
*s = 0;
295
pe->start = tmdate(t, &e, NiL);
296
if ((unsigned long)pe->start > state->now)
297
{
298
sfsprintf(pss->buf, sizeof(pss->buf), "last %s", t);
299
pe->start = tmdate(pss->buf, NiL, NiL);
300
}
301
*s = c;
302
if (e > s)
303
e = s;
304
break;
305
case PSS_state:
306
if ((pe->state = *(e = s)) == PSS_ZOMBIE)
307
*e = 0;
308
break;
309
case PSS_tgrp:
310
pe->tgrp = number(s, &e, 10);
311
break;
312
case PSS_time:
313
pe->time = strelapsed(s, &e, 1);
314
break;
315
case PSS_tty:
316
for (e = s; *e; e++)
317
if (isspace(*e))
318
{
319
*e++ = 0;
320
break;
321
}
322
pe->tty = pssttydev(pss, s);
323
break;
324
case PSS_uid:
325
for (e = s; *e; e++)
326
if (isspace(*e))
327
{
328
*e++ = 0;
329
break;
330
}
331
pe->uid = struid(s);
332
break;
333
case PSS_wchan:
334
pe->wchan = (void*)number(s, &e, 16);
335
break;
336
}
337
if (e == s)
338
while (*s && !isspace(*s))
339
s++;
340
else
341
s = e;
342
if (isspace(*s))
343
*s++ = 0;
344
}
345
return 1;
346
}
347
348
static Pssmeth_t ps_method =
349
{
350
"ps",
351
"[-version?@(#)$Id: pss ps (AT&T Research) 2003-02-01 $\n]"
352
"[-author?Glenn Fowler <[email protected]>]",
353
PSS_all,
354
ps_init,
355
ps_read,
356
ps_part,
357
0,
358
0,
359
0,
360
0,
361
ps_done
362
};
363
364
Pssmeth_t* _pss_ps = &ps_method;
365
366
#endif
367
368