/* * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include "top.h" /* Program options. */ 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; /* Prototypes. */ static void top_p_opts_parse(int a_argc, char **a_argv); static void top_p_usage(void); int main(int argc, char **argv) { /* Parse arguments. */ top_p_opts_parse(argc, argv); /* * Make sure the user doesn't mind logging mode, if not running on a * tty. */ if (isatty(0)) { if (top_opt_l) return log_run(); /* Run in logging mode. */ else return disp_run(); /* Run interactively. */ } else { // not a tty 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; /* Turn off automatic error reporting. */ opterr = 0; /* Iteratively process command line arguments. */ 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': /* Ignore. */ 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': /* Check for + or - prefix. */ 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': /* Check for + or - prefix. */ 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') { /* * The argument isn't a number. Try it as a * username. */ pwd = getpwnam(optarg); if (pwd != NULL) top_opt_U_uid = pwd->pw_uid; } else { /* Verify that the number is a valid uid. */ 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); } } /* Check for without preceding -n. */ 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++; } /* Check for trailing command line garbage. */ 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 ]\n\ [-F | -f]\n\ [-h]\n\ [-i ]\n\ [-k]\n\ [-L | -l ]\n\ [-o ] [-O ]\n\ [-p ] [-P ]\n\ [-R | -r]\n\ [-s ]\n\ [-T | -t]\n\ [-U ]\n\ [-u]\n\ [-W | -w]\n\ [-X | x]\n\ [[-n] ]\n"); }