hxtools/sadmin/proc_stat_parse.c

159 lines
5.6 KiB
C

// SPDX-License-Identifier: MIT
/*
* proc_stat_parse - turn /proc/N/stat into human-readable form
* written by Jan Engelhardt, 2012
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <libHX/init.h>
#include <libHX/string.h>
struct sp_task {
char comm[32], state;
int pid, ppid, pgid, sid, tty_nr, tty_pgrp;
unsigned int task_flags;
/*
* We have to use unsigned long long here, since the kernel's unsigned
* long may be longer than userspace's.
*/
unsigned long long min_flt, cmin_flt, max_flt, cmax_flt;
long long utime, stime, cutime, cstime;
int priority, nice, num_threads;
unsigned long long start_time, vsize, get_mm_rss, rsslim;
unsigned long long mm_start_code, mm_end_code, mm_start_stack;
unsigned long long sp, ip, sig_pend, sig_block, sig_ign, sig_catch;
unsigned long long wchan;
int exit_signal, task_cpu;
unsigned int task_rt_prio, task_policy;
unsigned long long da_blkio_ticks, gtime, cgtime, start_data;
unsigned long long end_data, start_brk;
};
static void sp_init_task(struct sp_task *p)
{
memset(p, 0, sizeof(*p));
}
static void sp_interp_line(const char *s)
{
struct sp_task t;
sp_init_task(&t);
sscanf(s,/*1 */ "%d %31s %c %d %d "
/* 6 */ "%d %d %d %u %llu "
/* 11 */ "%llu %llu %llu %llu %llu "
/* 16 */ "%llu %llu %d %d %d "
/* 21 */ "0 %llu %llu %llu %llu "
/* 26 */ "%llu %llu %llu %llu %llu "
/* 31 */ "%llu %llu %llu %llu %llu "
/* 36 */ "0 0 %d %d %u "
/* 41 */ "%u %llu %llu %lld %llu "
/* 46 */ "%llu %llu",
/* 1 */ &t.pid, t.comm, &t.state, &t.ppid, &t.pgid,
/* 6 */ &t.sid, &t.tty_nr, &t.tty_pgrp, &t.task_flags, &t.min_flt,
/* 11 */ &t.cmin_flt, &t.max_flt, &t.cmax_flt, &t.utime, &t.stime,
/* 16 */ &t.cutime, &t.cstime, &t.priority, &t.nice, &t.num_threads,
/* 21 */ /*,*/ &t.start_time, &t.vsize, &t.get_mm_rss, &t.rsslim,
/* 26 */ &t.mm_start_code, &t.mm_end_code, &t.mm_start_stack, &t.sp, &t.ip,
/* 31 */ &t.sig_pend, &t.sig_block, &t.sig_ign, &t.sig_catch, &t.wchan,
/* 36 */ /*,,*/ &t.exit_signal, &t.task_cpu, &t.task_rt_prio,
/* 41 */ &t.task_policy, &t.da_blkio_ticks, &t.gtime, &t.cgtime, &t.start_data,
/* 46 */ &t.end_data, &t.start_brk
);
printf("01 PID: %d\n", t.pid);
printf("02 Comm: %s\n", t.comm);
printf("03 State: %c\n", t.state);
printf("04 PPID: %d\n", t.ppid);
printf("05 PGID: %d\n", t.pgid);
printf("06 SID: %d\n", t.sid);
printf("07 tty_nr: %d\n", t.tty_nr);
printf("08 tty_pgrp: %d\n", t.tty_pgrp);
printf("09 task_flags: 0x%x\n", t.task_flags);
printf("10 min_flt: %llu\n", t.min_flt);
printf("11 cmin_flt: %llu\n", t.cmin_flt);
printf("12 max_flt: %llu\n", t.max_flt);
printf("13 cmax_flt: %llu\n", t.cmax_flt);
printf("14 utime: %lld clocks (= %lld s)\n",
t.utime, t.utime / CLOCKS_PER_SEC);
printf("15 stime: %lld clocks (= %lld s)\n",
t.stime, t.stime / CLOCKS_PER_SEC);
printf("16 cutime: %lld clocks (= %lld s)\n",
t.cutime, t.cutime / CLOCKS_PER_SEC);
printf("17 cstime: %lld clocks (= %lld s)\n",
t.cstime, t.cstime / CLOCKS_PER_SEC);
printf("18 priority: %d\n", t.priority);
printf("19 nice: %d\n", t.nice);
printf("20 num_threads: %d\n", t.num_threads);
printf("21 -- always 0\n");
printf("22 start_time: %llu\n", t.start_time);
printf("23 vsize: 0x%llx (%llu)\n", t.vsize, t.vsize);
printf("24 get_mm_rss: 0x%llx (%llu)\n", t.get_mm_rss, t.get_mm_rss);
printf("25 rsslim: 0x%llx (%llu)\n", t.rsslim, t.rsslim);
printf("26 mm_start_code: 0x%llx\n", t.mm_start_code);
printf("27 mm_end_code: 0x%llx\n", t.mm_end_code);
printf("28 mm_start_stack: 0x%llx\n", t.mm_start_stack);
printf("29 sp register: 0x%llx\n", t.sp);
printf("30 ip register: 0x%llx\n", t.ip);
printf("31 obsol-sig-pend: 0x%llx\n", t.sig_pend);
printf("32 obsol-sig-block: 0x%llx\n", t.sig_block);
printf("33 obsol-sig-ign: 0x%llx\n", t.sig_ign);
printf("34 obsol-sig-catch: 0x%llx\n", t.sig_catch);
printf("35 wchan: 0x%llx\n", t.wchan);
printf("36 -- always 0\n");
printf("37 -- always 0\n");
printf("38 task_exit_sig: %d\n", t.exit_signal);
printf("39 task_cpu: %d\n", t.task_cpu);
printf("40 task_rt_prio: %u\n", t.task_rt_prio);
printf("41 task_policy: %u\n", t.task_policy);
printf("42 delayacct_blkio: %llu ticks\n", t.da_blkio_ticks);
printf("43 gtime: %lld clocks (= %lld s)\n",
t.gtime, t.gtime / CLOCKS_PER_SEC);
printf("44 cgtime: %lld clocks (= %lld s)\n",
t.cgtime, t.cgtime / CLOCKS_PER_SEC);
printf("45 start_data: 0x%llx\n", t.start_data);
printf("46 end_data: 0x%llx\n", t.end_data);
printf("47 start_brk: 0x%llx\n", t.start_brk);
}
static void sp_interp_file(FILE *fp)
{
hxmc_t *line = NULL;
while (HX_getl(&line, fp) != NULL)
sp_interp_line(line);
HXmc_free(line);
}
int main(int argc, const char **argv)
{
const char *prog = argv[0];
int ret;
ret = HX_init();
if (ret <= 0) {
fprintf(stderr, "%s: HX_init: %s\n", prog, strerror(-ret));
return EXIT_FAILURE;
}
if (argc == 1) {
sp_interp_file(stdin);
HX_exit();
return EXIT_SUCCESS;
}
while (*++argv != NULL) {
FILE *fp = fopen(*argv, "r");
if (fp == NULL) {
fprintf(stderr, "%s: %s: %s\n",
prog, *argv, strerror(errno));
continue;
}
sp_interp_file(fp);
fclose(fp);
}
HX_exit();
return EXIT_SUCCESS;
}