27
27
#include <unistd.h>
28
28
#include <sys/stat.h>
33
#define DEV_ENCODE(M,m) ( \
34
( (M&0xfff) << 8) | ( (m&0xfff00) << 12) | (m&0xff) \
37
///////////////////////////////////////////////////////
39
#include <sys/mkdev.h>
40
#define _STRUCTURED_PROC 1
41
#include <sys/procfs.h>
42
#define NO_TTY_VALUE DEV_ENCODE(-1,-1)
43
#define HZ 1 // only bother with seconds
46
///////////////////////////////////////////////////////
48
#include <sys/param.h>
49
#include <sys/sysctl.h>
53
#define NO_TTY_VALUE DEV_ENCODE(-1,-1)
54
#define HZ 1 // only bother with seconds
57
///////////////////////////////////////////////////////
32
59
#include <asm/param.h> /* HZ */
33
60
#include <asm/page.h> /* PAGE_SIZE */
61
#define NO_TTY_VALUE DEV_ENCODE(0,0)
63
#warning HZ not defined, assuming it is 100
68
///////////////////////////////////////////////////////////
71
#warning PAGE_SIZE not defined, assuming it is 4096
72
#define PAGE_SIZE 4096
77
static char P_tty_text[16];
78
static char P_cmd[16];
37
static char P_cmd[16];
39
static int P_ppid, P_pgrp, P_session, P_tty, P_tpgid;
82
static int P_ppid, P_pgrp, P_session, P_tty_num, P_tpgid;
40
83
static unsigned long P_flags, P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime;
41
static long P_cutime, P_cstime, P_priority, P_nice, P_timeout, P_it_real_value;
84
static long P_cutime, P_cstime, P_priority, P_nice, P_timeout, P_alarm;
42
85
static unsigned long P_start_time, P_vsize;
44
87
static unsigned long P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip;
273
307
if(bsd_c_option) show_args = 0;
311
/* return 1 if it works, or 0 for failure */
312
static int stat2proc(int pid) {
313
struct psinfo p; // /proc/*/psinfo, struct psinfo, psinfo_t
317
int tty_maj, tty_min;
318
snprintf(buf, sizeof buf, "/proc/%d/psinfo", pid);
319
if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0;
320
num = read(fd, &p, sizeof p);
322
if(num != sizeof p) return 0;
325
if (num >= sizeof P_cmd) num = sizeof P_cmd - 1;
326
memcpy(P_cmd, p.pr_fname, num); // p.pr_fname or p.pr_lwp.pr_name
332
P_session = p.pr_sid;
336
P_start_time = p.pr_start.tv_sec;
337
P_wchan = p.pr_lwp.pr_wchan;
338
P_state = p.pr_lwp.pr_sname;
339
P_nice = p.pr_lwp.pr_nice;
340
P_priority = p.pr_lwp.pr_pri; // or pr_oldpri
341
// P_ruid = p.pr_uid;
342
// P_rgid = p.pr_gid;
343
// P_egid = p.pr_egid;
346
// don't support these
348
P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime;
349
P_cutime, P_cstime, P_timeout, P_alarm;
350
P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip;
351
P_signal, P_blocked, P_sigignore, P_sigcatch;
355
// we like it Linux-encoded :-)
356
tty_maj = major(p.pr_ttydev);
357
tty_min = minor(p.pr_ttydev);
358
P_tty_num = DEV_ENCODE(tty_maj,tty_min);
360
snprintf(P_tty_text, sizeof P_tty_text, "%3d,%-3d", tty_maj, tty_min);
362
if (tty_maj == 24) snprintf(P_tty_text, sizeof P_tty_text, "pts/%-3u", tty_min);
363
if (P_tty_num == NO_TTY_VALUE) memcpy(P_tty_text, " ? ", 8);
364
if (P_tty_num == DEV_ENCODE(0,0)) memcpy(P_tty_text, "console", 8);
367
if(P_pid != pid) return 0;
373
/* return 1 if it works, or 0 for failure */
374
static int stat2proc(int pid) {
379
int tty_maj, tty_min;
380
snprintf(buf, 32, "/proc/%d/status", pid);
381
if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0;
382
num = read(fd, buf, sizeof buf - 1);
389
// FreeBSD /proc/*/status is seriously fucked. Unlike the Linux
390
// files, we can't use strrchr to find the end of a command name.
391
// Spaces in command names do not get escaped. To avoid spoofing,
392
// one may skip 20 characters and then look _forward_ only to
393
// find a pattern of entries that are {with,with,without} a comma.
394
// The entry without a comma is wchan. Then count backwards!
396
// Don't bother for now. FreeBSD isn't worth the trouble.
398
tmp = strchr(buf,' ');
400
if (num >= sizeof P_cmd) num = sizeof P_cmd - 1;
401
memcpy(P_cmd,buf,num);
413
&P_pid, &P_ppid, &P_pgrp, &P_session,
415
/* SKIP funny flags thing */
416
&P_start_time, /* SKIP microseconds */
417
&P_utime, /* SKIP microseconds */
418
&P_stime, /* SKIP microseconds */
419
/* SKIP &P_wchan, for now -- it is a string */
420
&P_euid, &P_euid // don't know which is which
422
/* fprintf(stderr, "stat2proc converted %d fields.\n",num); */
424
snprintf(P_tty_text, sizeof P_tty_text, "%3d,%-3d", tty_maj, tty_min);
425
P_tty_num = DEV_ENCODE(tty_maj,tty_min);
426
// tty decode is 224 to 256 bytes on i386
429
if (tty_maj == 5) tmp = " ttyp%c ";
430
if (tty_maj == 12) tmp = " ttyv%c ";
431
if (tty_maj == 28) tmp = " ttyd%c ";
432
if (P_tty_num == NO_TTY_VALUE) tmp = " ? ";
433
if (P_tty_num == DEV_ENCODE(0,0)) tmp = "console";
434
if (P_tty_num == DEV_ENCODE(12,255)) tmp = "consolectl";
440
"0123456789abcdefghijklmnopqrstuvwxyz"[tty_min&31]
445
if(num < 9) return 0;
446
if(P_pid != pid) return 0;
276
452
/* return 1 if it works, or 0 for failure */
277
453
static int stat2proc(int pid) {
278
454
char buf[800]; /* about 40 fields, 64-bit decimal is about 20 chars */
304
480
"%u %u %u %u " /* no use for RT signals */
307
&P_ppid, &P_pgrp, &P_session, &P_tty, &P_tpgid,
483
&P_ppid, &P_pgrp, &P_session, &P_tty_num, &P_tpgid,
308
484
&P_flags, &P_min_flt, &P_cmin_flt, &P_maj_flt, &P_cmaj_flt, &P_utime, &P_stime,
309
&P_cutime, &P_cstime, &P_priority, &P_nice, &P_timeout, &P_it_real_value,
485
&P_cutime, &P_cstime, &P_priority, &P_nice, &P_timeout, &P_alarm,
310
486
&P_start_time, &P_vsize,
312
488
&P_rss_rlim, &P_start_code, &P_end_code, &P_start_stack, &P_kstk_esp, &P_kstk_eip,
372
557
static void print_proc(void){
374
snprintf(tty, sizeof tty, "%3d,%-3d", (P_tty>>8)&0xff, P_tty&0xff);
375
558
switch(ps_format){
377
printf("%5d %s %s", P_pid, tty, do_time(P_utime+P_stime));
560
printf("%5d %s %s", P_pid, P_tty_text, do_time(P_utime+P_stime));
380
563
printf("%d\n", P_pid);
381
564
return; /* don't want the command */
384
"%03x %c %5d %5d %5d %s %3d %3d - "
567
"0 %c %5d %5d %5d %s %3d %3d - "
385
568
"%5ld %06x %s %s",
386
(unsigned)P_flags&0x777, P_state, P_euid, P_pid, P_ppid, do_cpu(0),
569
P_state, P_euid, P_pid, P_ppid, do_cpu(0),
387
570
(int)P_priority, (int)P_nice, P_vsize/(PAGE_SIZE/1024),
388
(unsigned)(P_wchan&0xffffff), tty, do_time(P_utime+P_stime)
571
(unsigned)(P_wchan&0xffffff), P_tty_text, do_time(P_utime+P_stime)
393
576
"%8s %5d %5d %s %s %s %s",
394
do_user(), P_pid, P_ppid, do_cpu(0), do_stime(), tty, do_time(P_utime+P_stime)
577
do_user(), P_pid, P_ppid, do_cpu(0), do_stime(), P_tty_text, do_time(P_utime+P_stime)
399
582
"%5d %5d %5d %s %s",
400
P_pid, P_pgrp, P_session, tty, do_time(P_utime+P_stime)
583
P_pid, P_pgrp, P_session, P_tty_text, do_time(P_utime+P_stime)
405
588
"%8s %5d %s %s %5ld %4ld %s %c %s %s",
406
do_user(), P_pid, do_cpu(1), do_mem(1), P_vsize, P_rss, tty, P_state,
589
do_user(), P_pid, do_cpu(1), do_mem(1), P_vsize, P_rss, P_tty_text, P_state,
407
590
do_stime(), do_time(P_utime+P_stime)
412
595
"%5d %s %c %s %6d - - %5d %s",
413
P_pid, tty, P_state, do_time(P_utime+P_stime), (int)P_maj_flt,
596
P_pid, P_tty_text, P_state, do_time(P_utime+P_stime), (int)P_maj_flt,
414
597
(int)P_rss, do_mem(1)
419
602
"%5d %5d %5d %5d %s %5d %c %5d %s",
420
P_ppid, P_pid, P_pgrp, P_session, tty, P_tpgid, P_state, P_euid, do_time(P_utime+P_stime)
603
P_ppid, P_pid, P_pgrp, P_session, P_tty_text, P_tpgid, P_state, P_euid, do_time(P_utime+P_stime)
425
"%03x %5d %5d %5d %3d %3d "
608
"0 %5d %5d %5d %3d %3d "
426
609
"%5ld %4ld %06x %c %s %s",
427
(unsigned)P_flags&0x777, P_euid, P_pid, P_ppid, (int)P_priority, (int)P_nice,
428
P_vsize, P_rss, (unsigned)(P_wchan&0xffffff), P_state, tty, do_time(P_utime+P_stime)
610
P_euid, P_pid, P_ppid, (int)P_priority, (int)P_nice,
611
P_vsize, P_rss, (unsigned)(P_wchan&0xffffff), P_state, P_tty_text, do_time(P_utime+P_stime)
433
617
if(show_args) printf(" [%s]\n", P_cmd);
434
618
else printf(" %s\n", P_cmd);