Subject: Re: bin/32785 [dM] du not terabyte-clean
To: None <tech-userlevel@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-userlevel
Date: 07/24/2006 16:57:42
Okay.  Since prstat() uses int64_t (why not uint64_t?), there's no
point in going with uintmax_t here (for the benefit of PR readers,
uintmax_t was suggested in tech-userlevel discussion).  So here's
another patch.  If you want to change the type from uint64_t to
something else now, there's only one place to change now (the #define
of BIGVAL).

--- du.c.fcs	2006-07-24 13:26:08.000000000 -0400
+++ du.c	2006-07-24 16:56:53.000000000 -0400
@@ -190,12 +190,15 @@
 				}
 			}
 		}
+#define BIGVAL(p) (*(uint64_t *)p->fts_pointer)
 		switch (p->fts_info) {
-		case FTS_D:			/* Ignore. */
+		case FTS_D:
+			p->fts_pointer = malloc(sizeof(BIGVAL(p)));
+			BIGVAL(p) = 0;
 			break;
 		case FTS_DP:
-			p->fts_parent->fts_number += 
-			    p->fts_number += p->fts_statp->st_blocks;
+			BIGVAL(p) += p->fts_statp->st_blocks;
+			if (p->fts_parent->fts_pointer) BIGVAL(p->fts_parent) += BIGVAL(p);
 			if (cflag)
 				totalblocks += p->fts_statp->st_blocks;
 			/*
@@ -204,7 +207,9 @@
 			 * root of a traversal, display the total.
 			 */
 			if (listdirs || (!listfiles && !p->fts_level))
-				prstat(p->fts_path, p->fts_number);
+				prstat(p->fts_path, BIGVAL(p));
+			free(p->fts_pointer);
+			p->fts_pointer = 0;
 			break;
 		case FTS_DC:			/* Ignore. */
 			break;
@@ -224,10 +229,11 @@
 			 */
 			if (listfiles || !p->fts_level)
 				prstat(p->fts_path, p->fts_statp->st_blocks);
-			p->fts_parent->fts_number += p->fts_statp->st_blocks;
+			if (p->fts_parent->fts_pointer) BIGVAL(p->fts_parent) += p->fts_statp->st_blocks;
 			if (cflag)
 				totalblocks += p->fts_statp->st_blocks;
 		}
+#undef BIGVAL
 	}
 	if (errno)
 		err(1, "fts_read");

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B