--- /dev/null
+
+// parse_args.c
+
+#include <string.h>
+#include <unistd.h>
+
+#include "parse_args.h"
+
+static inline int parse_pid(const char *ptr, struct arg_pid_item *new_item) {
+ unsigned long pid = 0;
+ do {
+ if (parse_unsigned_long(&pid, *ptr, NULL) < 0)
+ return -1;
+ ptr++;
+ } while (*ptr != '\0' && *ptr != '+' && *ptr != '*');
+ *new_item = (struct arg_pid_item){ pid, *ptr };
+ if (ptr[0] != '\0' && ptr[1] != '\0')
+ return -1;
+ return 0;
+}
+
+static inline int parse_arg_pid(int argc, char ***argv, struct list *arg_pids) {
+ if (
+ list_maybe_grow(
+ arg_pids, ++arg_pids->len, sizeof (struct arg_pid_item)
+ ) < 0
+ )
+ return -1;
+ if ((**argv)[5] == '=') {
+ if (
+ parse_pid(
+ **argv + 6,
+ LIST_ITEMS(*arg_pids, struct arg_pid_item) + arg_pids->len - 1
+ ) < 0
+ )
+ return -1;
+ } else if ((**argv)[5] == '\0') {
+ if (
+ --argc == 0
+ || parse_pid(
+ *++(*argv),
+ LIST_ITEMS(*arg_pids, struct arg_pid_item) + arg_pids->len - 1
+ ) < 0
+ )
+ return -1;
+ } else
+ return -1;
+ return argc;
+}
+
+static inline int parse_delay(const char *ptr, struct timeval *delay) {
+ register unsigned long fractions;
+ *delay = (struct timeval){ 0, 0 };
+ for (; *ptr != '\0' && *ptr != '.'; ptr++)
+ if (parse_unsigned_long((unsigned long*)&delay->tv_sec, *ptr, NULL) < 0)
+ return -1;
+ ptr += *ptr != '\0';
+ for (
+ fractions = MICRO_IN_SEC / 10;
+ *ptr && fractions > 0;
+ ptr++, fractions /= 10
+ )
+ if (*ptr < '0' || *ptr > '9')
+ return -1;
+ else
+ delay->tv_usec += fractions * (*ptr - '0');
+ return 0;
+}
+
+static inline int parse_arg_delay(
+ int argc, char ***argv, struct timeval *delay
+) {
+ long clock_ticks;
+ if ((**argv)[7] == '=') {
+ if (parse_delay(**argv + 8, delay) < 0)
+ return -1;
+ } else if ((**argv)[7] == '\0') {
+ if (--argc == 0 || parse_delay(*++(*argv), delay) < 0)
+ return -1;
+ } else
+ return -1;
+ clock_ticks = sysconf(_SC_CLK_TCK);
+ if (
+ (clock_ticks <= 1 && delay->tv_sec < 1) || (
+ delay->tv_sec < 1 && delay->tv_usec < MICRO_IN_SEC / clock_ticks
+ )
+ ) {
+ fprintf(stderr, "Error: delay too small!\n");
+ return -1;
+ }
+ return argc;
+}
+
+int parse_args(
+ int argc,
+ char **argv,
+ struct list *pids,
+ struct timeval *delay,
+ int *humanize_mem
+) {
+ for (argc--, argv++; argc > 0; argc--, argv++) {
+ if (strncmp(*argv, "--pid", 5) == 0)
+ argc = parse_arg_pid(argc, &argv, pids);
+ else if (strncmp(*argv, "--delay", 7) == 0)
+ argc = parse_arg_delay(argc, &argv, delay);
+ else if (strcmp(*argv, "--humanize") == 0)
+ *humanize_mem = 1;
+ else
+ argc = -1;
+ if (argc == -1) {
+ fprintf(stderr, "Error: Could not process argument: '%s'\n", *argv);
+ return -1;
+ }
+ }
+ return 0;
+}
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
+#include "list.h"
+#include "parse_args.h"
+
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
-#define MICRO_IN_SEC 1000000
#define NANO_IN_SEC 1000000000
#define TIMESPEC_TO_DOUBLE(t) \
((double)(t).tv_sec + (double)(t).tv_nsec / NANO_IN_SEC)
#define TIMESPEC_ISZERO(t) ((t).tv_sec == 0 && (t).tv_nsec == 0)
-struct list {
- size_t len, allo;
- void *data;
-};
-#define LIST_EMPTY ((struct list){ 0, 0, NULL })
-#define LIST_ITEMS(l, t) ((t*)(l).data)
-#define LIST_POS(p, l, t) (size_t)((p) - LIST_ITEMS((l), t))
-#define LIST_AT(l, i, t) (LIST_ITEMS((l), t) + i)
-
-static inline int list_maybe_grow(
- struct list *l, size_t new_len, size_t item_size
-) {
- void *np;
- if (new_len <= l->allo)
- return 0;
- do
- l->allo = l->allo ? l->allo * 2 : 8;
- while (new_len > l->allo);
- np = realloc(l->data, l->allo * item_size);
- if (np == NULL) {
- perror("realloc");
- return -1;
- }
- l->data = np;
- return 0;
-}
-
-struct arg_pid_item {
- pid_t pid;
- char mode;
-};
-
-static inline int parse_unsigned_long(
- unsigned long *result, char c, char *label
-) {
- register unsigned long new_value = 10 * *result + c - '0';
- if (c >= '0' && new_value / 10 == *result) {
- *result = new_value;
- return 0;
- }
- if (label)
- fprintf(
- stderr,
- "Error: %s: invalid character or overflow ('%c')\n",
- label,
- c
- );
- return -1;
-}
-
-static inline int parse_pid(const char *ptr, struct arg_pid_item *new_item) {
- unsigned long pid = 0;
- do {
- if (parse_unsigned_long(&pid, *ptr, NULL) < 0)
- return -1;
- ptr++;
- } while (*ptr != '\0' && *ptr != '+' && *ptr != '*');
- *new_item = (struct arg_pid_item){ pid, *ptr };
- if (ptr[0] != '\0' && ptr[1] != '\0')
- return -1;
- return 0;
-}
-
-static inline int parse_arg_pid(int argc, char ***argv, struct list *arg_pids) {
- if (
- list_maybe_grow(
- arg_pids, ++arg_pids->len, sizeof (struct arg_pid_item)
- ) < 0
- )
- return -1;
- if ((**argv)[5] == '=') {
- if (
- parse_pid(
- **argv + 6,
- LIST_ITEMS(*arg_pids, struct arg_pid_item) + arg_pids->len - 1
- ) < 0
- )
- return -1;
- } else if ((**argv)[5] == '\0') {
- if (
- --argc == 0
- || parse_pid(
- *++(*argv),
- LIST_ITEMS(*arg_pids, struct arg_pid_item) + arg_pids->len - 1
- ) < 0
- )
- return -1;
- } else
- return -1;
- return argc;
-}
-
-static inline int parse_delay(const char *ptr, struct timeval *delay) {
- register unsigned long fractions;
- *delay = (struct timeval){ 0, 0 };
- for (; *ptr != '\0' && *ptr != '.'; ptr++)
- if (parse_unsigned_long((unsigned long*)&delay->tv_sec, *ptr, NULL) < 0)
- return -1;
- ptr += *ptr != '\0';
- for (
- fractions = MICRO_IN_SEC / 10;
- *ptr && fractions > 0;
- ptr++, fractions /= 10
- )
- if (*ptr < '0' || *ptr > '9')
- return -1;
- else
- delay->tv_usec += fractions * (*ptr - '0');
- return 0;
-}
-
-static inline int parse_arg_delay(
- int argc, char ***argv, struct timeval *delay
-) {
- long clock_ticks;
- if ((**argv)[7] == '=') {
- if (parse_delay(**argv + 8, delay) < 0)
- return -1;
- } else if ((**argv)[7] == '\0') {
- if (--argc == 0 || parse_delay(*++(*argv), delay) < 0)
- return -1;
- } else
- return -1;
- clock_ticks = sysconf(_SC_CLK_TCK);
- if (
- (clock_ticks <= 1 && delay->tv_sec < 1) || (
- delay->tv_sec < 1 && delay->tv_usec < MICRO_IN_SEC / clock_ticks
- )
- ) {
- fprintf(stderr, "Error: delay too small!\n");
- return -1;
- }
- return argc;
-}
-
-int parse_args(
- int argc,
- char **argv,
- struct list *pids,
- struct timeval *delay,
- int *humanize_mem
-) {
- for (argc--, argv++; argc > 0; argc--, argv++) {
- if (strncmp(*argv, "--pid", 5) == 0)
- argc = parse_arg_pid(argc, &argv, pids);
- else if (strncmp(*argv, "--delay", 7) == 0)
- argc = parse_arg_delay(argc, &argv, delay);
- else if (strcmp(*argv, "--humanize") == 0)
- *humanize_mem = 1;
- else
- argc = -1;
- if (argc == -1) {
- fprintf(stderr, "Error: Could not process argument: '%s'\n", *argv);
- return -1;
- }
- }
- return 0;
-}
static int alarm_set, int_set, page_size;
};
static inline void get_field_labels(char digits, char *buffer) {
- const char *s = "ppidvsizerss";
+ const char *s = "ppid\0vsize\0rss";
char *ptr = buffer;
for (digits &= 7; digits; digits >>= 1) {
if (!(digits & 1)) {
- s += 4;
- if (*s != 'u')
- s++;
+ s += 5 + (s[4] != '\0');
continue;
}
if (ptr > buffer) {
*ptr++ = ',';
*ptr++ = ' ';
}
- *ptr++ = *s++;
- *ptr++ = *s++;
- *ptr++ = *s++;
- if (!*s)
- break;
- *ptr++ = *s++;
- if (*s != 'u')
+ do
*ptr++ = *s++;
+ while (*s);
+ s++;
}
*ptr = '\0';
}