From 37133ba7027d430eccfe8b95c22c55c60ad8e4a1 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Mon, 19 Apr 2010 15:11:45 +0000 Subject: [PATCH] Slightly different handling of printf/snprintf for unaligned uint64_t, which should improve readability, and also to ease the port to platforms that do not support %llu MFC after: 3 days --- sbin/ipfw/dummynet.c | 8 +++--- sbin/ipfw/ipfw2.c | 66 +++++++++++++++++++++++--------------------- sbin/ipfw/ipfw2.h | 2 +- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c index eb6547a046c8..19d52a44b144 100644 --- a/sbin/ipfw/dummynet.c +++ b/sbin/ipfw/dummynet.c @@ -203,9 +203,9 @@ list_flow(struct dn_flow *ni) inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)), id->dst_port); } - printf("%4llu %8llu %2u %4u %3u\n", - align_uint64(&ni->tot_pkts), - align_uint64(&ni->tot_bytes), + pr_u64(&ni->tot_pkts, 4); + pr_u64(&ni->tot_bytes, 8); + printf("%2u %4u %3u\n", ni->length, ni->len_bytes, ni->drops); } @@ -290,8 +290,8 @@ static void list_pipes(struct dn_id *oid, struct dn_id *end) { char buf[160]; /* pending buffer */ - buf[0] = '\0'; + buf[0] = '\0'; for (; oid != end; oid = O_NEXT(oid, oid->len)) { if (oid->len < sizeof(*oid)) errx(1, "invalid oid len %d\n", oid->len); diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 41f6e3ab3e86..b0f76830c409 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -314,22 +314,27 @@ static struct _s_x rule_options[] = { { NULL, 0 } /* terminator */ }; -/* - * The following is used to generate a printable argument for - * 64-bit numbers, irrespective of platform alignment and bit size. - * Because all the printf in this program use %llu as a format, - * we just return an unsigned long long, which is larger than - * we need in certain cases, but saves the hassle of using - * PRIu64 as a format specifier. - * We don't care about inlining, this is not performance critical code. +/* + * Helper routine to print a possibly unaligned uint64_t on + * various platform. If width > 0, print the value with + * the desired width, followed by a space; + * otherwise, return the required width. */ -unsigned long long -align_uint64(const uint64_t *pll) +int +pr_u64(uint64_t *pd, int width) { - uint64_t ret; +#ifdef TCC +#define U64_FMT "I64" +#else +#define U64_FMT "llu" +#endif + uint64_t d; - bcopy (pll, &ret, sizeof(ret)); - return ret; + bcopy (pd, &d, sizeof(d)); + return (width > 0) ? + printf("%*" U64_FMT " ", width, d) : + snprintf(NULL, 0, "%" U64_FMT, d) ; +#undef U64_FMT } void * @@ -973,9 +978,10 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth) } printf("%05u ", rule->rulenum); - if (pcwidth>0 || bcwidth>0) - printf("%*llu %*llu ", pcwidth, align_uint64(&rule->pcnt), - bcwidth, align_uint64(&rule->bcnt)); + if (pcwidth > 0 || bcwidth > 0) { + pr_u64(&rule->pcnt, pcwidth); + pr_u64(&rule->bcnt, bcwidth); + } if (co.do_time == 2) printf("%10u ", rule->timestamp); @@ -1577,10 +1583,12 @@ show_dyn_ipfw(ipfw_dyn_rule *d, int pcwidth, int bcwidth) } bcopy(&d->rule, &rulenum, sizeof(rulenum)); printf("%05d", rulenum); - if (pcwidth>0 || bcwidth>0) - printf(" %*llu %*llu (%ds)", pcwidth, - align_uint64(&d->pcnt), bcwidth, - align_uint64(&d->bcnt), d->expire); + if (pcwidth > 0 || bcwidth > 0) { + printf(" "); + pr_u64(&d->pcnt, pcwidth); + pr_u64(&d->bcnt, bcwidth); + printf("(%ds)", d->expire); + } switch (d->dyn_type) { case O_LIMIT_PARENT: printf(" PARENT %d", d->count); @@ -1645,9 +1653,9 @@ ipfw_sets_handler(char *av[]) free(data); nalloc = nalloc * 2 + 200; nbytes = nalloc; - data = safe_calloc(1, nbytes); - if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0) - err(EX_OSERR, "getsockopt(IP_FW_GET)"); + data = safe_calloc(1, nbytes); + if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0) + err(EX_OSERR, "getsockopt(IP_FW_GET)"); } bcopy(&((struct ip_fw *)data)->next_rule, @@ -1837,14 +1845,12 @@ ipfw_list(int ac, char *av[], int show_counters) continue; /* packet counter */ - width = snprintf(NULL, 0, "%llu", - align_uint64(&r->pcnt)); + width = pr_u64(&r->pcnt, 0); if (width > pcwidth) pcwidth = width; /* byte counter */ - width = snprintf(NULL, 0, "%llu", - align_uint64(&r->bcnt)); + width = pr_u64(&r->bcnt, 0); if (width > bcwidth) bcwidth = width; } @@ -1858,13 +1864,11 @@ ipfw_list(int ac, char *av[], int show_counters) if (set != co.use_set - 1) continue; } - width = snprintf(NULL, 0, "%llu", - align_uint64(&d->pcnt)); + width = pr_u64(&d->pcnt, 0); if (width > pcwidth) pcwidth = width; - width = snprintf(NULL, 0, "%llu", - align_uint64(&d->bcnt)); + width = pr_u64(&d->bcnt, 0); if (width > bcwidth) bcwidth = width; } diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h index d1729841e97b..8566cdef0218 100644 --- a/sbin/ipfw/ipfw2.h +++ b/sbin/ipfw/ipfw2.h @@ -207,7 +207,7 @@ enum tokens { #define NEED(_p, msg) {if (!_p) errx(EX_USAGE, msg);} #define NEED1(msg) {if (!(*av)) errx(EX_USAGE, msg);} -unsigned long long align_uint64(const uint64_t *pll); +int pr_u64(uint64_t *pd, int width); /* memory allocation support */ void *safe_calloc(size_t number, size_t size);