#include "top.h"
char top_opt_c = 'n';
boolean_t top_opt_f = TRUE;
unsigned top_opt_i = 10;
boolean_t top_opt_L = FALSE;
boolean_t top_opt_l = FALSE;
unsigned top_opt_l_samples = 0;
unsigned top_opt_n = TOP_MAX_NPROCS;
top_sort_key_t top_opt_O = TOP_SORT_pid;
boolean_t top_opt_O_ascend = FALSE;
top_sort_key_t top_opt_o = TOP_SORT_pid;
boolean_t top_opt_o_ascend = FALSE;
char * top_opt_p_format=NULL;
char * top_opt_P_legend=NULL;
boolean_t top_opt_r = TRUE;
boolean_t top_opt_S = FALSE;
unsigned top_opt_s = 1;
boolean_t top_opt_t = FALSE;
boolean_t top_opt_U = FALSE;
boolean_t top_opt_U_uid = FALSE;
boolean_t top_opt_w = FALSE;
boolean_t top_opt_x = TRUE;
static void
top_p_opts_parse(int a_argc, char **a_argv);
static void
top_p_usage(void);
int
main(int argc, char **argv)
{
top_p_opts_parse(argc, argv);
if (isatty(0)) {
if (top_opt_l) return log_run();
else return disp_run();
} else { if (top_opt_L) {
fprintf(stderr, "top: Not running on a tty\n");
exit(1);
} else return log_run();
}
}
const char *
top_sort_key_str(top_sort_key_t a_key, boolean_t a_ascend)
{
const char *strings[] = {
"-command", "+command",
"-cpu", "+cpu",
"-pid", "+pid",
"-prt", "+prt",
"-reg", "+reg",
"-rprvt", "+rprvt",
"-rshrd", "+rshrd",
"-rsize", "+rsize",
"-th", "+th",
"-time", "+time",
"-uid", "+uid",
"-username", "+username",
"-vprvt", "+vprvt",
"-vsize", "+vsize"
};
return a_ascend ? strings[a_key * 2] : strings[a_key * 2 + 1];
}
static void
top_p_opts_parse(int a_argc, char **a_argv)
{
int c;
opterr = 0;
while ((c = getopt(a_argc, a_argv, "ac:deFfhi:kLl:n:O:o:p:P:RrSs:TtU:uWwXx")) != -1) {
switch (c) {
case 'a': case 'd': case 'e': top_opt_c = c; break;
case 'c':
top_opt_c = optarg[0];
switch (top_opt_c) {
case 'a': case 'd': case 'e': case 'n':
break;
default:
fprintf(stderr,
"top: Invalid argument: -c %s\n", optarg);
top_p_usage();
exit(1);
}
break;
case 'F': top_opt_f = FALSE; break;
case 'f': top_opt_f = TRUE; break;
case 'i': {
char *p;
errno = 0;
top_opt_i = strtoul(optarg, &p, 0);
if ((errno == EINVAL && top_opt_i == 0)
|| (errno == ERANGE
&& top_opt_i == ULONG_MAX)
|| top_opt_i < 1 || top_opt_i > TOP_MAX_INTERVAL
|| *p != '\0') {
fprintf(stderr,
"top: Invalid argument: -i %s\n", optarg);
top_p_usage();
exit(1);
}
break;
}
case 'h': top_p_usage(); exit(0);
case 'k': break;
case 'L': top_opt_L = TRUE; break;
case 'l': {
char *p;
top_opt_l = TRUE;
errno = 0;
top_opt_l_samples = strtoul(optarg, &p, 0);
if ((errno == EINVAL && top_opt_l_samples == 0)
|| (errno == ERANGE
&& top_opt_l_samples == ULONG_MAX)
|| *p != '\0') {
fprintf(stderr,
"top: Invalid argument: -l %s\n", optarg);
top_p_usage();
exit(1);
}
break;
}
case 'n': {
char *p;
errno = 0;
top_opt_n = strtoul(optarg, &p, 0);
if ((errno == EINVAL && top_opt_n == 0)
|| (errno == ERANGE && top_opt_n == ULONG_MAX)
|| *p != '\0'
|| top_opt_n > TOP_MAX_NPROCS) {
fprintf(stderr,
"top: Invalid argument: -n %s\n", optarg);
top_p_usage();
exit(1);
}
break;
}
case 'O':
if (optarg[0] == '+' || optarg[0] == '-') {
top_opt_O_ascend = (optarg[0] == '+');
optarg++;
}
if (strcasecmp(optarg, "command") == 0) top_opt_O = TOP_SORT_command;
else if (strcasecmp(optarg, "cpu") == 0) top_opt_O = TOP_SORT_cpu;
else if (strcasecmp(optarg, "pid") == 0) top_opt_O = TOP_SORT_pid;
else if (strcasecmp(optarg, "prt") == 0) top_opt_O = TOP_SORT_prt;
else if (strcasecmp(optarg, "reg") == 0) top_opt_O = TOP_SORT_reg;
else if (strcasecmp(optarg, "rprvt") == 0) top_opt_O = TOP_SORT_rprvt;
else if (strcasecmp(optarg, "rshrd") == 0) top_opt_O = TOP_SORT_rshrd;
else if (strcasecmp(optarg, "rsize") == 0) top_opt_O = TOP_SORT_rsize;
else if (strcasecmp(optarg, "th") == 0) top_opt_O = TOP_SORT_th;
else if (strcasecmp(optarg, "time") == 0) top_opt_O = TOP_SORT_time;
else if (strcasecmp(optarg, "uid") == 0) top_opt_O = TOP_SORT_uid;
else if (strcasecmp(optarg, "username") == 0) top_opt_O = TOP_SORT_username;
else if (strcasecmp(optarg, "vprvt") == 0) top_opt_O = TOP_SORT_vprvt;
else if (strcasecmp(optarg, "vsize") == 0) top_opt_O = TOP_SORT_vsize;
else {
fprintf(stderr, "top: Invalid argument: -O %s\n", optarg);
top_p_usage();
exit(1);
}
break;
case 'o':
if (optarg[0] == '+' || optarg[0] == '-') {
top_opt_o_ascend = (optarg[0] == '+');
optarg++;
}
if (strcasecmp(optarg, "command") == 0) top_opt_o = TOP_SORT_command;
else if (strcasecmp(optarg, "cpu") == 0) top_opt_o = TOP_SORT_cpu;
else if (strcasecmp(optarg, "pid") == 0) top_opt_o = TOP_SORT_pid;
else if (strcasecmp(optarg, "prt") == 0) top_opt_o = TOP_SORT_prt;
else if (strcasecmp(optarg, "reg") == 0) top_opt_o = TOP_SORT_reg;
else if (strcasecmp(optarg, "rprvt") == 0) top_opt_o = TOP_SORT_rprvt;
else if (strcasecmp(optarg, "rshrd") == 0) top_opt_o = TOP_SORT_rshrd;
else if (strcasecmp(optarg, "rsize") == 0) top_opt_o = TOP_SORT_rsize;
else if (strcasecmp(optarg, "th") == 0) top_opt_o = TOP_SORT_th;
else if (strcasecmp(optarg, "time") == 0) top_opt_o = TOP_SORT_time;
else if (strcasecmp(optarg, "uid") == 0) top_opt_o = TOP_SORT_uid;
else if (strcasecmp(optarg, "username") == 0) top_opt_o = TOP_SORT_username;
else if (strcasecmp(optarg, "vprvt") == 0) top_opt_o = TOP_SORT_vprvt;
else if (strcasecmp(optarg, "vsize") == 0) top_opt_o = TOP_SORT_vsize;
else {
fprintf(stderr, "top: Invalid argument: -o %s\n", optarg);
top_p_usage();
exit(1);
}
break;
case 'P':
top_opt_P_legend = (char *)malloc(strlen(optarg));
strcpy(top_opt_P_legend, optarg);
break;
case 'p':
top_opt_p_format = (char *)malloc(strlen(optarg));
strcpy(top_opt_p_format, optarg);
break;
case 'R': top_opt_r = FALSE; break;
case 'r': top_opt_r = TRUE; break;
case 'S': top_opt_S = TRUE; break;
case 's': {
char *p;
errno = 0;
top_opt_s = strtoul(optarg, &p, 0);
if ((errno == EINVAL && top_opt_s == 0)
|| (errno == ERANGE && top_opt_s == ULONG_MAX)
|| *p != '\0') {
fprintf(stderr, "top: Invalid argument: -s %s\n", optarg);
top_p_usage();
exit(1);
}
break;
}
case 'T': top_opt_t = FALSE; break;
case 't': top_opt_t = TRUE; break;
case 'U': {
char *p;
struct passwd *pwd;
top_opt_U = TRUE;
errno = 0;
top_opt_U_uid = strtoul(optarg, &p, 0);
if ((errno == EINVAL && top_opt_U_uid == 0)
|| (errno == ERANGE && top_opt_U_uid == ULONG_MAX)
|| *p != '\0') {
pwd = getpwnam(optarg);
if (pwd != NULL) top_opt_U_uid = pwd->pw_uid;
} else {
pwd = getpwuid((uid_t)top_opt_U_uid);
}
endpwent();
if (pwd == NULL) {
fprintf(stderr, "top: Invalid argument: -U %s\n", optarg);
top_p_usage();
exit(1);
}
break;
}
case 'u':
top_opt_o = TOP_SORT_cpu;
top_opt_O = TOP_SORT_time;
break;
case 'W': top_opt_w = FALSE; break;
case 'w': top_opt_w = TRUE; break;
case 'X': top_opt_x = FALSE; break;
case 'x':
top_opt_x = TRUE;
top_opt_s = 1;
top_opt_S = FALSE;
break;
case '?':
default:
fprintf(stderr, "top: Unrecognized or missing option %c\n",optopt);
top_p_usage();
exit(1);
}
}
if (optind < a_argc) {
char *p;
errno = 0;
top_opt_n = strtoul(a_argv[optind], &p, 0);
if ((errno == EINVAL && top_opt_n == 0)
|| (errno == ERANGE && top_opt_n == ULONG_MAX)
|| *p != '\0'
|| top_opt_n > TOP_MAX_NPROCS) {
fprintf(stderr, "top: Invalid argument: %s\n", a_argv[optind]);
top_p_usage();
exit(1);
}
optind++;
}
if (optind < a_argc) {
fprintf(stderr, "top: Unrecognized trailing arguments:");
for (; optind < a_argc; optind++) fprintf(stderr, " %s", a_argv[optind]);
fprintf(stderr, "\n");
top_p_usage();
exit(1);
}
}
static void
top_p_usage(void)
{
fprintf(stderr, "\
top usage: top [-a | -d | -e | -c <mode>]\n\
[-F | -f]\n\
[-h]\n\
[-i <interval>]\n\
[-k]\n\
[-L | -l <samples>]\n\
[-o <key>] [-O <skey>]\n\
[-p <format>] [-P <legend>]\n\
[-R | -r]\n\
[-s <delay>]\n\
[-T | -t]\n\
[-U <user>]\n\
[-u]\n\
[-W | -w]\n\
[-X | x]\n\
[[-n] <nprocs>]\n");
}