Changeset View
Standalone View
usr.bin/procstat/procstat.c
/*- | /*- | ||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | ||||
* | * | ||||
* Copyright (c) 2007, 2011 Robert N. M. Watson | * Copyright (c) 2007, 2011 Robert N. M. Watson | ||||
* Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> | * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> | ||||
* Copyright (c) 2017 Dell EMC | * Copyright (c) 2017 Dell EMC | ||||
* Copyright (c) 2020 Juraj Lutter <juraj@lutter.sk> | |||||
kib: New files definitely must get your copyright notice, but changes to existing files do not seems… | |||||
* 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 | ||||
* notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
* documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. | ||||
* | * | ||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
Done Inline ActionsThese two lines with just '*' should be removed. kib: These two lines with just '*' should be removed. | |||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
Done Inline ActionsCan you extract that sweep into separate review ? kib: Can you extract that sweep into separate review ? | |||||
#include <sys/user.h> | #include <sys/user.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <libprocstat.h> | #include <libprocstat.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <sysexits.h> | #include <sysexits.h> | ||||
Show All 9 Lines | |||||
struct procstat_cmd { | struct procstat_cmd { | ||||
const char *command; | const char *command; | ||||
const char *xocontainer; | const char *xocontainer; | ||||
const char *usage; | const char *usage; | ||||
void (*cmd)(struct procstat *, struct kinfo_proc *); | void (*cmd)(struct procstat *, struct kinfo_proc *); | ||||
void (*opt)(int, char * const *); | void (*opt)(int, char * const *); | ||||
int cmp; | int cmp; | ||||
int mode; | |||||
kibUnsubmitted Done Inline Actions'cmp' is really a general-purpose flag field. I do not see why would you need one more field ('more'), and why do you need PS_MODE_NORMAL: only COMPAT needs treatment. kib: 'cmp' is really a general-purpose flag field. I do not see why would you need one more field… | |||||
}; | }; | ||||
int procstat_opts = 0; | int procstat_opts = 0; | ||||
int procstat_mode = PS_MODE_NORMAL; | |||||
Done Inline ActionsNo space after '*'. kib: No space after '*'. | |||||
const char * xocontainer; | |||||
static void cmdopt_none(int argc, char * const argv[]); | static void cmdopt_none(int argc, char * const argv[]); | ||||
static void cmdopt_verbose(int argc, char * const argv[]); | static void cmdopt_verbose(int argc, char * const argv[]); | ||||
static void cmdopt_signals(int argc, char * const argv[]); | static void cmdopt_signals(int argc, char * const argv[]); | ||||
static void cmdopt_rusage(int argc, char * const argv[]); | static void cmdopt_rusage(int argc, char * const argv[]); | ||||
static void cmdopt_files(int argc, char * const argv[]); | static void cmdopt_files(int argc, char * const argv[]); | ||||
static void cmdopt_cpuset(int argc, char * const argv[]); | static void cmdopt_cpuset(int argc, char * const argv[]); | ||||
static void usage_procstat(void); | |||||
static void usage_compat(void); | |||||
/* pointer to actual usage function */ | |||||
static void (*usage_func)(void); | |||||
static const char *progname; | |||||
/* aliased program parameters and arguments | |||||
* - usage field is abused to hold the pointer to the function | |||||
* displaying program usage | |||||
*/ | |||||
static const struct procstat_cmd pacmd_table[] = { | |||||
{ "pwdx", "pwd", (const char *)&usage_compat, &procstat_compat_pwdx, &cmdopt_none, | |||||
PS_CMP_NORMAL, PS_MODE_COMPAT }, | |||||
/* arguments are the same as for pwdx: pid or core file */ | |||||
{ "penv", "env", (const char *)&usage_compat, &procstat_compat_penv, &cmdopt_none, | |||||
PS_CMP_NORMAL, PS_MODE_COMPAT }, | |||||
{ "pargs", "args", (const char *)&usage_compat, &procstat_compat_pargs, &cmdopt_none, | |||||
PS_CMP_NORMAL, PS_MODE_COMPAT } | |||||
}; | |||||
/* procstat parameters and arguments */ | |||||
static const struct procstat_cmd cmd_table[] = { | static const struct procstat_cmd cmd_table[] = { | ||||
{ "argument", "arguments", NULL, &procstat_args, &cmdopt_none, | { "argument", "arguments", NULL, &procstat_args, &cmdopt_none, | ||||
PS_CMP_PLURAL | PS_CMP_SUBSTR }, | PS_CMP_PLURAL | PS_CMP_SUBSTR, PS_MODE_NORMAL }, | ||||
{ "auxv", "auxv", NULL, &procstat_auxv, &cmdopt_none, PS_CMP_NORMAL }, | { "auxv", "auxv", NULL, &procstat_auxv, &cmdopt_none, PS_CMP_NORMAL, | ||||
PS_MODE_NORMAL }, | |||||
{ "basic", "basic", NULL, &procstat_basic, &cmdopt_none, | { "basic", "basic", NULL, &procstat_basic, &cmdopt_none, | ||||
PS_CMP_NORMAL }, | PS_CMP_NORMAL, PS_MODE_NORMAL }, | ||||
{ "binary", "binary", NULL, &procstat_bin, &cmdopt_none, | { "binary", "binary", NULL, &procstat_bin, &cmdopt_none, | ||||
PS_CMP_SUBSTR }, | PS_CMP_SUBSTR, PS_MODE_NORMAL }, | ||||
{ "cpuset", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL }, | { "cpuset", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL, | ||||
{ "cs", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL }, | PS_MODE_NORMAL }, | ||||
{ "cs", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL, | |||||
PS_MODE_NORMAL }, | |||||
{ "credential", "credentials", NULL, &procstat_cred, &cmdopt_none, | { "credential", "credentials", NULL, &procstat_cred, &cmdopt_none, | ||||
PS_CMP_PLURAL | PS_CMP_SUBSTR }, | PS_CMP_PLURAL | PS_CMP_SUBSTR, PS_MODE_NORMAL }, | ||||
{ "environment", "environment", NULL, &procstat_env, &cmdopt_none, | { "environment", "environment", NULL, &procstat_env, &cmdopt_none, | ||||
PS_CMP_SUBSTR }, | PS_CMP_SUBSTR, PS_MODE_NORMAL }, | ||||
{ "fd", "files", "[-C]", &procstat_files, &cmdopt_files, | { "fd", "files", "[-C]", &procstat_files, &cmdopt_files, | ||||
PS_CMP_PLURAL }, | PS_CMP_PLURAL, PS_MODE_NORMAL }, | ||||
{ "file", "files", "[-C]", &procstat_files, &cmdopt_files, | { "file", "files", "[-C]", &procstat_files, &cmdopt_files, | ||||
PS_CMP_PLURAL }, | PS_CMP_PLURAL, PS_MODE_NORMAL }, | ||||
{ "kstack", "kstack", "[-v]", &procstat_kstack, &cmdopt_verbose, | { "kstack", "kstack", "[-v]", &procstat_kstack, &cmdopt_verbose, | ||||
PS_CMP_NORMAL }, | PS_CMP_NORMAL, PS_MODE_NORMAL }, | ||||
{ "ptlwpinfo", "ptlwpinfo", NULL, &procstat_ptlwpinfo, &cmdopt_none, | { "ptlwpinfo", "ptlwpinfo", NULL, &procstat_ptlwpinfo, &cmdopt_none, | ||||
PS_CMP_NORMAL }, | PS_CMP_NORMAL, PS_MODE_NORMAL }, | ||||
{ "rlimit", "rlimit", NULL, &procstat_rlimit, &cmdopt_none, | { "rlimit", "rlimit", NULL, &procstat_rlimit, &cmdopt_none, | ||||
PS_CMP_NORMAL }, | PS_CMP_NORMAL, PS_MODE_NORMAL }, | ||||
{ "rusage", "rusage", "[-Ht]", &procstat_rusage, &cmdopt_rusage, | { "rusage", "rusage", "[-Ht]", &procstat_rusage, &cmdopt_rusage, | ||||
PS_CMP_NORMAL }, | PS_CMP_NORMAL, PS_MODE_NORMAL }, | ||||
{ "sigfastblock", "sigfastblock", NULL, &procstat_sigfastblock, | { "sigfastblock", "sigfastblock", NULL, &procstat_sigfastblock, | ||||
&cmdopt_none, PS_CMP_NORMAL }, | &cmdopt_none, PS_CMP_NORMAL, PS_MODE_NORMAL }, | ||||
{ "signal", "signals", "[-n]", &procstat_sigs, &cmdopt_signals, | { "signal", "signals", "[-n]", &procstat_sigs, &cmdopt_signals, | ||||
PS_CMP_PLURAL | PS_CMP_SUBSTR }, | PS_CMP_PLURAL | PS_CMP_SUBSTR, PS_MODE_NORMAL }, | ||||
{ "thread", "threads", NULL, &procstat_threads, &cmdopt_none, | { "thread", "threads", NULL, &procstat_threads, &cmdopt_none, | ||||
PS_CMP_PLURAL }, | PS_CMP_PLURAL, PS_MODE_NORMAL }, | ||||
{ "tsignal", "thread_signals", "[-n]", &procstat_threads_sigs, | { "tsignal", "thread_signals", "[-n]", &procstat_threads_sigs, | ||||
&cmdopt_signals, PS_CMP_PLURAL | PS_CMP_SUBSTR }, | &cmdopt_signals, PS_CMP_PLURAL | PS_CMP_SUBSTR, PS_MODE_NORMAL }, | ||||
{ "vm", "vm", NULL, &procstat_vm, &cmdopt_none, PS_CMP_NORMAL } | { "vm", "vm", NULL, &procstat_vm, &cmdopt_none, PS_CMP_NORMAL, | ||||
PS_MODE_NORMAL } | |||||
}; | }; | ||||
kibUnsubmitted Done Inline ActionsThere is definitive value in adding these p* things as normal procstat commands. Then I am not even sure that hardlinks for solaris compat are very useful, but I do not object. kib: There is definitive value in adding these p* things as normal procstat commands. Then I am not… | |||||
kibUnsubmitted Done Inline ActionsI probably miss something but I do not see how this suggestion was handled. kib: I probably miss something but I do not see how this suggestion was handled. | |||||
static void | static void | ||||
usage(void) | usage_procstat(void) | ||||
{ | { | ||||
size_t i, l; | size_t i, l; | ||||
int multi; | int multi; | ||||
xo_error("usage: procstat [--libxo] [-h] [-M core] [-N system]" | xo_error("usage: procstat [--libxo] [-h] [-M core] [-N system]" | ||||
" [-w interval] command\n" | " [-w interval] command\n" | ||||
" [pid ... | core ...]\n" | " [pid ... | core ...]\n" | ||||
" procstat [--libxo] -a [-h] [-M core] [-N system] " | " procstat [--libxo] -a [-h] [-M core] [-N system] " | ||||
Show All 26 Lines | if (cmd_table[i].usage != NULL) | ||||
xo_error(" %s", cmd_table[i].usage); | xo_error(" %s", cmd_table[i].usage); | ||||
xo_error("\n"); | xo_error("\n"); | ||||
} | } | ||||
xo_finish(); | xo_finish(); | ||||
exit(EX_USAGE); | exit(EX_USAGE); | ||||
} | } | ||||
static void | static void | ||||
usage_compat(void) | |||||
{ | |||||
xo_error("usage: %s [--libxo] pid ...\n", progname); | |||||
xo_finish(); | |||||
exit(EX_USAGE); | |||||
} | |||||
static void | |||||
usage(void) | |||||
{ | |||||
if (usage_func != NULL) | |||||
usage_func(); | |||||
else | |||||
usage_procstat(); | |||||
} | |||||
static void | |||||
procstat(const struct procstat_cmd *cmd, struct procstat *prstat, | procstat(const struct procstat_cmd *cmd, struct procstat *prstat, | ||||
struct kinfo_proc *kipp) | struct kinfo_proc *kipp) | ||||
{ | { | ||||
char *pidstr = NULL; | char *pidstr = NULL; | ||||
if ((procstat_opts & PS_OPT_NOPIDSTR) == 0) { | |||||
asprintf(&pidstr, "%d", kipp->ki_pid); | asprintf(&pidstr, "%d", kipp->ki_pid); | ||||
if (pidstr == NULL) | if (pidstr == NULL) | ||||
xo_errc(1, ENOMEM, "Failed to allocate memory in procstat()"); | xo_errc(1, ENOMEM, "Failed to allocate memory in procstat()"); | ||||
xo_open_container(pidstr); | xo_open_container(pidstr); | ||||
} | |||||
cmd->cmd(prstat, kipp); | cmd->cmd(prstat, kipp); | ||||
if ((procstat_opts & PS_OPT_NOPIDSTR) == 0) { | |||||
xo_close_container(pidstr); | xo_close_container(pidstr); | ||||
free(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) | ||||
{ | { | ||||
int i; | int i; | ||||
Show All 25 Lines | if (name[0] == '\0' || strcmp(kipp->ki_comm, name) == 0) { | ||||
name[0] = '-'; | name[0] = '-'; | ||||
name[1] = '\0'; | name[1] = '\0'; | ||||
} | } | ||||
return (name); | return (name); | ||||
} | } | ||||
static const struct procstat_cmd * | static const struct procstat_cmd * | ||||
getcmdbyprogname(const char *pprogname) | |||||
{ | |||||
size_t i, len; | |||||
const char *ca; | |||||
if (pprogname == NULL) | |||||
return NULL; | |||||
kibUnsubmitted Not Done Inline Actionsreturn (NULL). Style requires taking the returned value in braces. Please handle all places, I do not want to repeat it N times. kib: return (NULL). Style requires taking the returned value in braces. Please handle all places… | |||||
len = strlen(pprogname); | |||||
for (i = 0; i < nitems(pacmd_table); i++) { | |||||
ca = pacmd_table[i].command; | |||||
if (ca != NULL && | |||||
strlen(ca) == len && | |||||
kibUnsubmitted Not Done Inline ActionsContinuation line should have indent +4 spaces. kib: Continuation line should have indent +4 spaces. | |||||
Not Done Inline ActionsWhy do you use strncmp there ? You are ignoring arbitrary suffixes of ca, so e.g. just 'p' as pprogname would match first command starting with 'p'. kib: Why do you use strncmp there ? You are ignoring arbitrary suffixes of ca, so e.g. just 'p' as… | |||||
strncmp(pprogname + len - strlen(ca), ca, strlen(ca)) == 0) { | |||||
kibUnsubmitted Not Done Inline ActionsI do not understand what are you trying to do there. Are you trying to skip path prefix. like '/PATH/penv' ? Then use strrchr() perhaps. Right now you accept something like 'ppenv' as well. kib: I do not understand what are you trying to do there. Are you trying to skip path prefix. like… | |||||
return &pacmd_table[i]; | |||||
} | |||||
} | |||||
return NULL; | |||||
} | |||||
static const struct procstat_cmd * | |||||
getcmd(const char *str) | getcmd(const char *str) | ||||
{ | { | ||||
const struct procstat_cmd *cmd; | const struct procstat_cmd *cmd; | ||||
size_t i, l; | size_t i, l; | ||||
int cmp, s; | int cmp, s; | ||||
if (str == NULL) | if (str == NULL) | ||||
return (NULL); | return NULL; | ||||
cmd = NULL; | cmd = NULL; | ||||
if ((l = strlen(str)) == 0) | if ((l = strlen(str)) == 0) | ||||
return (getcmd("basic")); | return (getcmd("basic")); | ||||
s = l > 1 && strcasecmp(str + l - 1, "s") == 0; | s = l > 1 && strcasecmp(str + l - 1, "s") == 0; | ||||
for (i = 0; i < nitems(cmd_table); i++) { | for (i = 0; i < nitems(cmd_table); i++) { | ||||
/* | /* | ||||
* After the first match substring matches are disabled, | * After the first match substring matches are disabled, | ||||
* allowing subsequent full matches to take precedence. | * allowing subsequent full matches to take precedence. | ||||
Show All 25 Lines | main(int argc, char *argv[]) | ||||
char *dummy; | char *dummy; | ||||
char *nlistf, *memf; | char *nlistf, *memf; | ||||
int aflag; | int aflag; | ||||
int cnt; | int cnt; | ||||
interval = 0; | interval = 0; | ||||
cmd = NULL; | cmd = NULL; | ||||
memf = nlistf = NULL; | memf = nlistf = NULL; | ||||
progname = NULL; | |||||
aflag = 0; | aflag = 0; | ||||
argc = xo_parse_args(argc, argv); | argc = xo_parse_args(argc, argv); | ||||
progname = getprogname(); | |||||
cmd = getcmdbyprogname(progname); | |||||
if ((cmd != NULL) && (cmd->usage != NULL)) { | |||||
kibUnsubmitted Done Inline ActionsExcessive (). kib: Excessive (). | |||||
usage_func = (const void*)(cmd->usage); | |||||
kibUnsubmitted Done Inline Actionsusage_func = (const void *)cmd->usage. But case of function to void * is not portable. Also I do not see a need in this hack, just check flag for cmd as needed in usage(). kib: `usage_func = (const void *)cmd->usage`.
But case of function to void * is not portable. Also… | |||||
} | |||||
while ((ch = getopt(argc, argv, "abCcefHhijkLlM:N:nrSstvw:x")) != -1) { | while ((ch = getopt(argc, argv, "abCcefHhijkLlM:N:nrSstvw:x")) != -1) { | ||||
switch (ch) { | switch (ch) { | ||||
case 'a': | case 'a': | ||||
aflag++; | aflag++; | ||||
break; | break; | ||||
case 'b': | case 'b': | ||||
if (cmd != NULL) | if (cmd != NULL) | ||||
usage(); | usage(); | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | while ((ch = getopt(argc, argv, "abCcefHhijkLlM:N:nrSstvw:x")) != -1) { | ||||
default: | default: | ||||
usage(); | usage(); | ||||
} | } | ||||
} | } | ||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
if (cmd == NULL && argv[0] != NULL && (cmd = getcmd(argv[0])) != NULL) { | if (cmd == NULL && argv[0] != NULL) | ||||
cmd = getcmd(argv[0]); | |||||
if (cmd != NULL) { | |||||
if ((procstat_opts & PS_SUBCOMMAND_OPTS) != 0) | if ((procstat_opts & PS_SUBCOMMAND_OPTS) != 0) | ||||
usage(); | usage(); | ||||
procstat_mode = cmd->mode; | |||||
if (cmd->opt != NULL) { | if (cmd->opt != NULL) { | ||||
optreset = 1; | optreset = 1; | ||||
optind = 1; | optind = 1; | ||||
cmd->opt(argc, argv); | cmd->opt(argc, argv); | ||||
if (procstat_mode == PS_MODE_NORMAL) { | |||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
} | |||||
} else { | } else { | ||||
argc -= 1; | argc -= 1; | ||||
argv += 1; | argv += 1; | ||||
} | } | ||||
} else { | } else { | ||||
if (cmd == NULL) | |||||
cmd = getcmd("basic"); | cmd = getcmd("basic"); | ||||
} | |||||
if (cmd->cmd != procstat_files && | if (cmd->cmd != procstat_files && | ||||
(procstat_opts & PS_OPT_CAPABILITIES) != 0) | (procstat_opts & PS_OPT_CAPABILITIES) != 0 && | ||||
procstat_mode == 0) | |||||
usage(); | usage(); | ||||
} | |||||
/* Must specify either the -a flag or a list of pids. */ | /* Must specify either the -a flag or a list of pids. */ | ||||
if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0)) | if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0)) | ||||
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) | ||||
xo_errx(1, "procstat_open()"); | xo_errx(1, "procstat_open()"); | ||||
do { | do { | ||||
xocontainer = (cmd->xocontainer != NULL) ? cmd->xocontainer : cmd->command; | |||||
kibUnsubmitted Done Inline ActionsExtra (). kib: Extra (). | |||||
xo_set_version(PROCSTAT_XO_VERSION); | xo_set_version(PROCSTAT_XO_VERSION); | ||||
xo_open_container("procstat"); | xo_open_container(progname); | ||||
xo_open_container(cmd->xocontainer); | 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) | ||||
xo_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(cmd, prstat, &p[i]); | procstat(cmd, prstat, &p[i]); | ||||
Show All 14 Lines | for (i = 0; i < argc; i++) { | ||||
p = procstat_getprocs(prstat, KERN_PROC_PID, | p = procstat_getprocs(prstat, KERN_PROC_PID, | ||||
pid, &cnt); | pid, &cnt); | ||||
if (p == NULL) | if (p == NULL) | ||||
xo_errx(1, "procstat_getprocs()"); | xo_errx(1, "procstat_getprocs()"); | ||||
if (cnt != 0) | if (cnt != 0) | ||||
procstat(cmd, prstat, p); | procstat(cmd, prstat, p); | ||||
procstat_freeprocs(prstat, p); | procstat_freeprocs(prstat, p); | ||||
} else { | } else { | ||||
if (procstat_mode == PS_MODE_NORMAL) { | |||||
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) | ||||
xo_errx(1, "procstat_getprocs()"); | xo_errx(1, "procstat_getprocs()"); | ||||
if (cnt != 0) | if (cnt != 0) | ||||
procstat(cmd, cprstat, p); | procstat(cmd, cprstat, p); | ||||
procstat_freeprocs(cprstat, p); | procstat_freeprocs(cprstat, p); | ||||
procstat_close(cprstat); | procstat_close(cprstat); | ||||
} else { | |||||
usage(); | |||||
} | } | ||||
} | |||||
if (procstat_mode == PS_MODE_NORMAL) { | |||||
/* Suppress header after first process. */ | /* Suppress header after first process. */ | ||||
procstat_opts |= PS_OPT_NOHEADER; | procstat_opts |= PS_OPT_NOHEADER; | ||||
} | } | ||||
} | |||||
xo_close_container(cmd->xocontainer); | xo_close_container(xocontainer); | ||||
xo_close_container("procstat"); | xo_close_container(progname); | ||||
xo_finish(); | xo_finish(); | ||||
if (interval) | if (interval) | ||||
sleep(interval); | sleep(interval); | ||||
} while (interval); | } while (interval); | ||||
procstat_close(prstat); | procstat_close(prstat); | ||||
exit(0); | exit(0); | ||||
▲ Show 20 Lines • Show All 93 Lines • Show Last 20 Lines |
New files definitely must get your copyright notice, but changes to existing files do not seems to warrant addition of the copyright holder. Our usual bar is 20% of code from the copyright holder.