Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/procstat/procstat.c
/*- | /*- | ||||
* Copyright (c) 2007, 2011 Robert N. M. Watson | * Copyright (c) 2007, 2011 Robert N. M. Watson | ||||
* Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> | |||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
Show All 31 Lines | |||||
static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, rflag; | static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, rflag; | ||||
static int sflag, tflag, vflag, xflag, Sflag; | static int sflag, tflag, vflag, xflag, Sflag; | ||||
int hflag, nflag, Cflag, Hflag; | int hflag, nflag, Cflag, Hflag; | ||||
static void | static void | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
fprintf(stderr, "usage: procstat [-CHhn] [-M core] [-N system] " | xo_error("usage: procstat [-CHhn] [-M core] [-N system] " | ||||
"[-w interval] \n"); | "[-w interval]\n" | ||||
fprintf(stderr, " [-b | -c | -e | -f | -i | -j | -k | " | " [-b | -c | -e | -f | -i | -j | -k | " | ||||
"-l | -r | -s | -S | -t | -v | -x]\n"); | "-l | -r | -s | -S | -t | -v | -x]\n" | ||||
fprintf(stderr, " [-a | pid | core ...]\n"); | " [-a | pid | core ...]\n"); | ||||
xo_finish(); | |||||
exit(EX_USAGE); | exit(EX_USAGE); | ||||
} | } | ||||
static void | static void | ||||
procstat(struct procstat *prstat, struct kinfo_proc *kipp) | procstat(struct procstat *prstat, struct kinfo_proc *kipp) | ||||
{ | { | ||||
char *pidstr = NULL; | |||||
asprintf(&pidstr, "%d", kipp->ki_pid); | |||||
if (pidstr == NULL) | |||||
xo_errc(1, ENOMEM, "Failed to allocate memory in procstat()"); | |||||
xo_open_container(pidstr); | |||||
if (bflag) | if (bflag) | ||||
procstat_bin(prstat, kipp); | procstat_bin(prstat, kipp); | ||||
else if (cflag) | else if (cflag) | ||||
procstat_args(prstat, kipp); | procstat_args(prstat, kipp); | ||||
else if (eflag) | else if (eflag) | ||||
procstat_env(prstat, kipp); | procstat_env(prstat, kipp); | ||||
else if (fflag) | else if (fflag) | ||||
procstat_files(prstat, kipp); | procstat_files(prstat, kipp); | ||||
Show All 14 Lines | procstat(struct procstat *prstat, struct kinfo_proc *kipp) | ||||
else if (vflag) | else if (vflag) | ||||
procstat_vm(prstat, kipp); | procstat_vm(prstat, kipp); | ||||
else if (xflag) | else if (xflag) | ||||
procstat_auxv(prstat, kipp); | procstat_auxv(prstat, kipp); | ||||
else if (Sflag) | else if (Sflag) | ||||
procstat_cs(prstat, kipp); | procstat_cs(prstat, kipp); | ||||
else | else | ||||
procstat_basic(kipp); | procstat_basic(kipp); | ||||
xo_close_container(pidstr); | |||||
free(pidstr); | |||||
} | } | ||||
/* | /* | ||||
* Sort processes first by pid and then tid. | * Sort processes first by pid and then tid. | ||||
*/ | */ | ||||
static int | static int | ||||
kinfo_proc_compare(const void *a, const void *b) | kinfo_proc_compare(const void *a, const void *b) | ||||
{ | { | ||||
Show All 21 Lines | main(int argc, char *argv[]) | ||||
int ch, interval, tmp; | int ch, interval, tmp; | ||||
int i; | int i; | ||||
struct kinfo_proc *p; | struct kinfo_proc *p; | ||||
struct procstat *prstat, *cprstat; | struct procstat *prstat, *cprstat; | ||||
long l; | long l; | ||||
pid_t pid; | pid_t pid; | ||||
char *dummy; | char *dummy; | ||||
char *nlistf, *memf; | char *nlistf, *memf; | ||||
const char *xocontainer; | |||||
int cnt; | int cnt; | ||||
interval = 0; | interval = 0; | ||||
memf = nlistf = NULL; | memf = nlistf = NULL; | ||||
argc = xo_parse_args(argc, argv); | |||||
xocontainer = "basic"; | |||||
while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrsStvw:x")) != -1) { | while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrsStvw:x")) != -1) { | ||||
switch (ch) { | switch (ch) { | ||||
case 'C': | case 'C': | ||||
Cflag++; | Cflag++; | ||||
break; | break; | ||||
case 'H': | case 'H': | ||||
Hflag++; | Hflag++; | ||||
break; | break; | ||||
case 'M': | case 'M': | ||||
memf = optarg; | memf = optarg; | ||||
break; | break; | ||||
case 'N': | case 'N': | ||||
nlistf = optarg; | nlistf = optarg; | ||||
break; | break; | ||||
case 'S': | case 'S': | ||||
Sflag++; | Sflag++; | ||||
xocontainer = "cs"; | |||||
break; | break; | ||||
case 'a': | case 'a': | ||||
aflag++; | aflag++; | ||||
break; | break; | ||||
case 'b': | case 'b': | ||||
bflag++; | bflag++; | ||||
xocontainer = "binary"; | |||||
break; | break; | ||||
case 'c': | case 'c': | ||||
cflag++; | cflag++; | ||||
xocontainer = "arguments"; | |||||
break; | break; | ||||
case 'e': | case 'e': | ||||
eflag++; | eflag++; | ||||
xocontainer = "environment"; | |||||
break; | break; | ||||
case 'f': | case 'f': | ||||
fflag++; | fflag++; | ||||
xocontainer = "files"; | |||||
break; | break; | ||||
case 'i': | case 'i': | ||||
iflag++; | iflag++; | ||||
xocontainer = "signals"; | |||||
break; | break; | ||||
case 'j': | case 'j': | ||||
jflag++; | jflag++; | ||||
xocontainer = "thread_signals"; | |||||
break; | break; | ||||
case 'k': | case 'k': | ||||
kflag++; | kflag++; | ||||
xocontainer = "kstack"; | |||||
break; | break; | ||||
case 'l': | case 'l': | ||||
lflag++; | lflag++; | ||||
xocontainer = "rlimit"; | |||||
break; | break; | ||||
case 'n': | case 'n': | ||||
nflag++; | nflag++; | ||||
break; | break; | ||||
case 'h': | case 'h': | ||||
hflag++; | hflag++; | ||||
break; | break; | ||||
case 'r': | case 'r': | ||||
rflag++; | rflag++; | ||||
xocontainer = "rusage"; | |||||
break; | break; | ||||
case 's': | case 's': | ||||
sflag++; | sflag++; | ||||
xocontainer = "credentials"; | |||||
break; | break; | ||||
case 't': | case 't': | ||||
tflag++; | tflag++; | ||||
xocontainer = "threads"; | |||||
break; | break; | ||||
case 'v': | case 'v': | ||||
vflag++; | vflag++; | ||||
xocontainer = "vm"; | |||||
break; | break; | ||||
case 'w': | case 'w': | ||||
l = strtol(optarg, &dummy, 10); | l = strtol(optarg, &dummy, 10); | ||||
if (*dummy != '\0') | if (*dummy != '\0') | ||||
usage(); | usage(); | ||||
if (l < 1 || l > INT_MAX) | if (l < 1 || l > INT_MAX) | ||||
usage(); | usage(); | ||||
interval = l; | interval = l; | ||||
break; | break; | ||||
case 'x': | case 'x': | ||||
xflag++; | xflag++; | ||||
xocontainer = "auxv"; | |||||
break; | break; | ||||
case '?': | case '?': | ||||
default: | default: | ||||
usage(); | usage(); | ||||
} | } | ||||
} | } | ||||
Show All 18 Lines | main(int argc, char *argv[]) | ||||
if (Cflag && !fflag) | if (Cflag && !fflag) | ||||
usage(); | usage(); | ||||
if (memf != NULL) | if (memf != NULL) | ||||
prstat = procstat_open_kvm(nlistf, memf); | prstat = procstat_open_kvm(nlistf, memf); | ||||
else | else | ||||
prstat = procstat_open_sysctl(); | prstat = procstat_open_sysctl(); | ||||
if (prstat == NULL) | if (prstat == NULL) | ||||
errx(1, "procstat_open()"); | xo_errx(1, "procstat_open()"); | ||||
do { | do { | ||||
xo_set_version(PROCSTAT_XO_VERSION); | |||||
xo_open_container("procstat"); | |||||
xo_open_container(xocontainer); | |||||
if (aflag) { | if (aflag) { | ||||
p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt); | p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt); | ||||
if (p == NULL) | if (p == NULL) | ||||
errx(1, "procstat_getprocs()"); | xo_errx(1, "procstat_getprocs()"); | ||||
kinfo_proc_sort(p, cnt); | kinfo_proc_sort(p, cnt); | ||||
for (i = 0; i < cnt; i++) { | for (i = 0; i < cnt; i++) { | ||||
procstat(prstat, &p[i]); | procstat(prstat, &p[i]); | ||||
/* Suppress header after first process. */ | /* Suppress header after first process. */ | ||||
hflag = 1; | hflag = 1; | ||||
xo_flush(); | |||||
} | } | ||||
procstat_freeprocs(prstat, p); | procstat_freeprocs(prstat, p); | ||||
} | } | ||||
for (i = 0; i < argc; i++) { | for (i = 0; i < argc; i++) { | ||||
l = strtol(argv[i], &dummy, 10); | l = strtol(argv[i], &dummy, 10); | ||||
if (*dummy == '\0') { | if (*dummy == '\0') { | ||||
if (l < 0) | if (l < 0) | ||||
usage(); | usage(); | ||||
pid = l; | pid = l; | ||||
p = procstat_getprocs(prstat, KERN_PROC_PID, pid, &cnt); | p = procstat_getprocs(prstat, KERN_PROC_PID, | ||||
pid, &cnt); | |||||
if (p == NULL) | if (p == NULL) | ||||
errx(1, "procstat_getprocs()"); | xo_errx(1, "procstat_getprocs()"); | ||||
if (cnt != 0) | if (cnt != 0) | ||||
procstat(prstat, p); | procstat(prstat, p); | ||||
procstat_freeprocs(prstat, p); | procstat_freeprocs(prstat, p); | ||||
} else { | } else { | ||||
cprstat = procstat_open_core(argv[i]); | cprstat = procstat_open_core(argv[i]); | ||||
if (cprstat == NULL) { | if (cprstat == NULL) { | ||||
warnx("procstat_open()"); | warnx("procstat_open()"); | ||||
continue; | continue; | ||||
} | } | ||||
p = procstat_getprocs(cprstat, KERN_PROC_PID, | p = procstat_getprocs(cprstat, KERN_PROC_PID, | ||||
-1, &cnt); | -1, &cnt); | ||||
if (p == NULL) | if (p == NULL) | ||||
errx(1, "procstat_getprocs()"); | xo_errx(1, "procstat_getprocs()"); | ||||
if (cnt != 0) | if (cnt != 0) | ||||
procstat(cprstat, p); | procstat(cprstat, p); | ||||
procstat_freeprocs(cprstat, p); | procstat_freeprocs(cprstat, p); | ||||
procstat_close(cprstat); | procstat_close(cprstat); | ||||
} | } | ||||
/* Suppress header after first process. */ | /* Suppress header after first process. */ | ||||
hflag = 1; | hflag = 1; | ||||
} | } | ||||
xo_close_container(xocontainer); | |||||
xo_close_container("procstat"); | |||||
xo_finish(); | |||||
if (interval) | if (interval) | ||||
sleep(interval); | sleep(interval); | ||||
} while (interval); | } while (interval); | ||||
procstat_close(prstat); | procstat_close(prstat); | ||||
exit(0); | exit(0); | ||||
} | } |