return argc;
}
+static inline void print_help_and_exit(const char *argv0) {
+ printf(
+ (
+ "Usage: %s [-h|--help] [--delay DELAY] [--humanize] --pid PID ...\n"
+ "\n"
+ "Options:\n"
+ "-h, --help display this help\n"
+ "--delay A timeval (ms) in which to measure\n"
+ "--humanize Print memory human-readable rather than bytes\n"
+ "--pid PID Process ids to track. Specify multiple times\n"
+ " PID+ track all the direct child processes\n"
+ " PID* track all child processes recursively\n"
+ "\n"
+ ),
+ argv0
+ );
+ exit(0);
+}
+
int parse_args(
int argc,
char **argv,
struct timeval *delay,
int *humanize_mem
) {
+ const char *argv0 = *argv;
for (argc--, argv++; argc > 0; argc--, argv++) {
if (strncmp(*argv, "--pid", 5) == 0)
argc = parse_arg_pid(argc, &argv, pids);
argc = parse_arg_delay(argc, &argv, delay);
else if (strcmp(*argv, "--humanize") == 0)
*humanize_mem = 1;
- else
+ else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
+ if (pids->len > 0)
+ free(pids->data);
+ print_help_and_exit(argv0);
+ } else
argc = -1;
if (argc == -1) {
fprintf(stderr, "Error: Could not process argument: '%s'\n", *argv);
return -1;
}
}
+ if (pids->len == 0) {
+ fprintf(stderr, "Error: At least one pid must be passed.\n");
+ return -1;
+ }
return 0;
}
setup_signal_handler(SIGALRM, handle_alarm) < 0
|| setup_signal_handler(SIGINT, handle_int) < 0
)
- goto error;
+ return EXIT_FAILURE;
+ if (parse_args(argc, argv, &pids, &delay, &humanize_mem) < 0)
+ return EXIT_FAILURE;
if (
setitimer(
ITIMER_REAL, &(struct itimerval){ delay, delay }, NULL
perror("setitimer");
goto error;
}
- if (parse_args(argc, argv, &pids, &delay, &humanize_mem) < 0)
- return EXIT_FAILURE;
printf("[\n");
for (alarm_set = 0; alarm_await(); alarm_set = 0) {
if (clock_gettime(CLOCK_REALTIME, ¤t) < 0) {