| Summary: | /usr/bin/wc overflows at 2^32 | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Nicholas Barnes <nb> |
| Component: | bin | Assignee: | Sheldon Hearn <sheldonh> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 2.2.8-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->feedback The internal counters are already u_long. Presumeably, you want them to be quad_t? Could you try it and see what the performance hit is like on an Intel machine? Responsible Changed From-To: freebsd-bugs->sheldonh I'll take this one. I've tested the following diff for performance and see no noticeable
loss. I will say that I think it's perverse to demand the use of a
quad_int to store the number of lines in a file and a little less
perverse to do the same for the number of words, but since it doesn't
seem to cost us much, it's probably okay.
Would you like to test this? Paticularly, I haven't checked that the
printf()'s all do the right thing in all cases.
Ciao,
Sheldon.
Index: wc.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/wc/wc.c,v
retrieving revision 1.8
diff -u -d -r1.8 wc.c
--- wc.c 1997/08/25 06:44:59 1.8
+++ wc.c 1999/08/04 14:24:53
@@ -58,7 +58,7 @@
#include <string.h>
#include <unistd.h>
-u_long tlinect, twordct, tcharct;
+quad_t tlinect, twordct, tcharct;
int doline, doword, dochar;
int cnt __P((char *));
@@ -70,7 +70,7 @@
char *argv[];
{
register int ch;
- int errors, total;
+ quad_t errors, total;
(void) setlocale(LC_CTYPE, "");
@@ -114,11 +114,11 @@
if (total > 1) {
if (doline)
- (void)printf(" %7ld", tlinect);
+ (void)printf(" %7qu", tlinect);
if (doword)
- (void)printf(" %7ld", twordct);
+ (void)printf(" %7qu", twordct);
if (dochar)
- (void)printf(" %7ld", tcharct);
+ (void)printf(" %7qu", tcharct);
(void)printf(" total\n");
}
exit(errors == 0 ? 0 : 1);
@@ -131,7 +131,7 @@
register u_char *p, ch;
register short gotsp;
register int len;
- register u_long linect, wordct, charct;
+ register quad_t linect, wordct, charct;
struct stat sb;
int fd;
u_char buf[MAXBSIZE];
@@ -165,10 +165,10 @@
++linect;
}
tlinect += linect;
- (void)printf(" %7lu", linect);
+ (void)printf(" %7qu", linect);
if (dochar) {
tcharct += charct;
- (void)printf(" %7lu", charct);
+ (void)printf(" %7qu", charct);
}
(void)close(fd);
return (0);
@@ -219,15 +219,15 @@
}
if (doline) {
tlinect += linect;
- (void)printf(" %7lu", linect);
+ (void)printf(" %7qu", linect);
}
if (doword) {
twordct += wordct;
- (void)printf(" %7lu", wordct);
+ (void)printf(" %7qu", wordct);
}
if (dochar) {
tcharct += charct;
- (void)printf(" %7lu", charct);
+ (void)printf(" %7qu", charct);
}
(void)close(fd);
return (0);
Nick pointed me at the NetBSD changes, which highlight a glaring error
in my 2 minute noodles diff (the printf conversion specifiers).
Ciao,
Sheldon.
Index: wc.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/wc/wc.c,v
retrieving revision 1.8
diff -u -d -r1.8 wc.c
--- wc.c 1997/08/25 06:44:59 1.8
+++ wc.c 1999/08/04 14:24:53
@@ -58,7 +58,7 @@
#include <string.h>
#include <unistd.h>
-u_long tlinect, twordct, tcharct;
+quad_t tlinect, twordct, tcharct;
int doline, doword, dochar;
int cnt __P((char *));
@@ -70,7 +70,7 @@
char *argv[];
{
register int ch;
- int errors, total;
+ quad_t errors, total;
(void) setlocale(LC_CTYPE, "");
@@ -114,11 +114,11 @@
if (total > 1) {
if (doline)
- (void)printf(" %7ld", tlinect);
+ (void)printf(" %7qd", tlinect);
if (doword)
- (void)printf(" %7ld", twordct);
+ (void)printf(" %7qd", twordct);
if (dochar)
- (void)printf(" %7ld", tcharct);
+ (void)printf(" %7qd", tcharct);
(void)printf(" total\n");
}
exit(errors == 0 ? 0 : 1);
@@ -131,7 +131,7 @@
register u_char *p, ch;
register short gotsp;
register int len;
- register u_long linect, wordct, charct;
+ register quad_t linect, wordct, charct;
struct stat sb;
int fd;
u_char buf[MAXBSIZE];
@@ -165,10 +165,10 @@
++linect;
}
tlinect += linect;
- (void)printf(" %7lu", linect);
+ (void)printf(" %7qd", linect);
if (dochar) {
tcharct += charct;
- (void)printf(" %7lu", charct);
+ (void)printf(" %7qd", charct);
}
(void)close(fd);
return (0);
@@ -219,15 +219,15 @@
}
if (doline) {
tlinect += linect;
- (void)printf(" %7lu", linect);
+ (void)printf(" %7qd", linect);
}
if (doword) {
twordct += wordct;
- (void)printf(" %7lu", wordct);
+ (void)printf(" %7qd", wordct);
}
if (dochar) {
tcharct += charct;
- (void)printf(" %7lu", charct);
+ (void)printf(" %7qd", charct);
}
(void)close(fd);
return (0);
*sigh* Let me slow down, have a cup of coffee and then merge NetBSD's changes properly -- NetBSD is a lot better at getting past bde than OpenBSD. Ciao, Sheldon. State Changed From-To: feedback->closed Fixed in rev 1.9 of wc.c . |
/usr/bin/wc overflows at 2^32, so passing it a big file (or stream) gives bogus results. Fix: I'm sure a simple hack in the wc sources could make the counters 64-bit. How-To-Repeat: $ dd if=/dev/zero bs=1m count=4097 | wc 4097+0 records in 4097+0 records out 4296015872 bytes transferred in 614.248991 secs (6993932 bytes/sec) 1048576 $