[BusyBox] bug#1145: busybox-0.50 file offsets should be off_t not size_t

Jari Ruusu jari.ruusu at pp.inet.fi
Thu Apr 5 17:52:39 UTC 2001


Package: busybox
Version: 0.50
        
Jari Ruusu wrote:
> Without changes file copying should work for files smaller than 2G, but
> should fail for larger files (with -D_FILE_OFFSET_BITS=64 defined + LFS
> kernel + LFS glibc, that is).

Correction: limit is actually 4G not 2G.

Included patch fixes these problems:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1)  Above mentioned file copy problem with command "cp"
2)  Output of "ls" file size displayed half of what it should be when
    BB_FEATURE_HUMAN_READABLE is not defined.
3)  make_human_readable_str() didn't work well. Actually "ls -lh" didn't
    work at all. "ls" now correctly displays large file sizes.

Regards,
Jari Ruusu <jari.ruusu at pp.inet.fi>


--- ar.c.orig	Wed Feb 14 23:23:05 2001
+++ ar.c	Wed Apr  4 20:27:35 2001
@@ -211,7 +211,7 @@
 		}
 		if ((funct & extract_to_file) || (funct & extract_to_stdout)) {
 			lseek(srcFd, extract_list->offset, SEEK_SET);
-			copy_file_chunk(srcFd, dstFd, (size_t) extract_list->size);			
+			copy_file_chunk(srcFd, dstFd, (off_t) extract_list->size);
 		}
 		if (funct & verbose) {
 			printf("%s %d/%d %8d %s ", mode_string(extract_list->mode), 
--- busybox.h.orig	Wed Mar 14 03:36:52 2001
+++ busybox.h	Wed Apr  4 21:09:44 2001
@@ -120,7 +120,7 @@
 
 int copy_file(const char *srcName, const char *destName,
 		 int setModes, int followLinks, int forceFlag);
-int copy_file_chunk(int srcFd, int dstFd, size_t remaining);
+int copy_file_chunk(int srcFd, int dstFd, off_t remaining);
 char *buildName(const char *dirName, const char *fileName);
 int makeString(int argc, const char **argv, char *buf, int bufLen);
 char *getChunk(int size);
@@ -248,7 +248,7 @@
 #endif
 
 #ifdef BB_FEATURE_HUMAN_READABLE
-const char *make_human_readable_str(unsigned long val, unsigned long hr);
+const char *make_human_readable_str(unsigned long long val, unsigned long hr);
 #endif
 enum {
 	KILOBYTE = 1024,
--- df.c.orig	Sat Mar 10 00:42:26 2001
+++ df.c	Thu Apr  5 00:21:30 2001
@@ -40,9 +40,6 @@
 	struct statfs s;
 	long blocks_used;
 	long blocks_percent_used;
-#ifdef BB_FEATURE_HUMAN_READABLE
-	long base;
-#endif	
 
 	if (statfs(mount_point, &s) != 0) {
 		perror_msg("%s", mount_point);
@@ -63,26 +60,15 @@
 			find_real_root_device_name( device);
 		}
 #ifdef BB_FEATURE_HUMAN_READABLE
-		switch (df_disp_hr) {
-			case MEGABYTE:
-				base = KILOBYTE;
-				break;
-			case KILOBYTE:
-				base = 1;
-				break;
-			default:
-				base = 0;
-		}
 		printf("%-20s %9s ", device,
-			   make_human_readable_str((unsigned long)(s.f_blocks * 
-					   (s.f_bsize/(double)KILOBYTE)), base));
+			   make_human_readable_str((unsigned long long)s.f_blocks * 
+					   s.f_bsize, df_disp_hr));
 		printf("%9s ",
-			   make_human_readable_str((unsigned long)(
-					   (s.f_blocks - s.f_bfree) * 
-					   (s.f_bsize/(double)KILOBYTE)), base));
+			   make_human_readable_str((unsigned long long)(s.f_blocks - s.f_bfree) * 
+					   s.f_bsize, df_disp_hr));
 		printf("%9s %3ld%% %s\n",
-			   make_human_readable_str((unsigned long)(s.f_bavail * 
-					   (s.f_bsize/(double)KILOBYTE)), base),
+			   make_human_readable_str((unsigned long long)s.f_bavail * 
+					   s.f_bsize, df_disp_hr),
 			   blocks_percent_used, mount_point);
 #else
 		printf("%-20s %9ld %9ld %9ld %3ld%% %s\n",
--- ls.c.orig	Fri Mar  9 23:24:12 2001
+++ ls.c	Wed Apr  4 20:25:21 2001
@@ -652,9 +652,9 @@
 								(ls_disp_hr==TRUE)? 0: 1));
 #else
 #if _FILE_OFFSET_BITS == 64
-					printf("%9lld ", dn->dstat.st_size>>1);
+					printf("%9lld ", dn->dstat.st_size);
 #else
-					printf("%9ld ", dn->dstat.st_size>>1);
+					printf("%9ld ", dn->dstat.st_size);
 #endif
 #endif
 				}
--- utility.c.orig	Wed Mar 14 02:43:16 2001
+++ utility.c	Thu Apr  5 01:06:37 2001
@@ -335,7 +335,7 @@
 /*
  * Copy chunksize bytes between two file descriptors
  */
-int copy_file_chunk(int srcfd, int dstfd, size_t chunksize)
+int copy_file_chunk(int srcfd, int dstfd, off_t chunksize)
 {
         size_t size;
         char buffer[BUFSIZ]; /* BUFSIZ is declared in stdio.h */
@@ -1797,23 +1797,25 @@
 #endif
 
 #ifdef BB_FEATURE_HUMAN_READABLE
-const char *make_human_readable_str(unsigned long val, unsigned long hr)
+const char *make_human_readable_str(unsigned long long val, unsigned long hr)
 {
 	int i=0;
-	static char str[10] = "\0";
-	static const char strings[] = { 'k', 'M', 'G', 'T', 0 };
-	unsigned long divisor = 1;
-
-	if(val == 0)
-		return("0");
-	if(hr)
-		snprintf(str, 9, "%ld", val/hr);
-	else {
-		while(val >= divisor && i <= 4) {
-			divisor=divisor<<10, i++;
+	static char str[20];
+	static const char strings[] = { 0, 'k', 'M', 'G', 'T' };
+	unsigned long long divisor = 1 << 10;
+
+	if(hr) {
+		val += hr >> 1;
+		val /= hr;
+		noSuffix:
+		snprintf(str, 19, "%lld", val);
+	} else {
+		while(val >= divisor && i < 4) {
+			divisor <<= 10, i++;
 		} 
-		divisor=divisor>>10, i--;
-		snprintf(str, 9, "%.1Lf%c", (long double)(val)/divisor, strings[i]);
+		if(!i) goto noSuffix;
+		divisor >>= 10;
+		snprintf(str, 19, "%.1Lf%c", (long double)val / divisor, strings[i]);
 	}
 	return(str);
 }






More information about the busybox mailing list