From jaakko@saunalahti.fi  Wed Jul 16 15:08:12 2008
Return-Path: <jaakko@saunalahti.fi>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id C17981065675
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 16 Jul 2008 15:08:12 +0000 (UTC)
	(envelope-from jaakko@saunalahti.fi)
Received: from gw02.mail.saunalahti.fi (gw02.mail.saunalahti.fi [195.197.172.116])
	by mx1.freebsd.org (Postfix) with ESMTP id 57EC78FC32
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 16 Jul 2008 15:08:12 +0000 (UTC)
	(envelope-from jaakko@saunalahti.fi)
Received: from ws64.jh.dy.fi (a91-153-120-204.elisa-laajakaista.fi [91.153.120.204])
	by gw02.mail.saunalahti.fi (Postfix) with ESMTP id 58C3D1396E0
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 16 Jul 2008 18:08:10 +0300 (EEST)
Received: from ws64.jh.dy.fi (localhost [127.0.0.1])
	by ws64.jh.dy.fi (8.14.2/8.14.2) with ESMTP id m6GF8AxA004184
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 16 Jul 2008 18:08:10 +0300 (EEST)
	(envelope-from jaakko@ws64.jh.dy.fi)
Received: (from jaakko@localhost)
	by ws64.jh.dy.fi (8.14.2/8.14.2/Submit) id m6GF89PP004183;
	Wed, 16 Jul 2008 18:08:09 +0300 (EEST)
	(envelope-from jaakko)
Message-Id: <200807161508.m6GF89PP004183@ws64.jh.dy.fi>
Date: Wed, 16 Jul 2008 18:08:09 +0300 (EEST)
From: Jaakko Heinonen <jh@saunalahti.fi>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] ls(1) -h option doesn't work if the listing contains a device file
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         125678
>Category:       bin
>Synopsis:       [patch] ls(1) -h option doesn't work if the listing contains a device file
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    jh
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 16 15:10:01 UTC 2008
>Closed-Date:    Wed Feb 24 15:37:54 UTC 2010
>Last-Modified:  Wed Feb 24 15:37:54 UTC 2010
>Originator:     Jaakko Heinonen
>Release:        FreeBSD 7.0-STABLE / 8.0-CURRENT
>Organization:
>Environment:
	
>Description:

If a ls(1) long formatted listing has at least one character or block device
file the -h switch has no effect.

>How-To-Repeat:

$ ls -lh 10MBnull 
-rw-r--r--  1 jaakko  jaakko    10M Jul 16 13:29 10MBnull
$ ls -lh /dev/null 10MBnull 
crw-rw-rw-  1 root    wheel     0,  26 Jul 16 13:22 /dev/null
-rw-r--r--  1 jaakko  jaakko  10485760 Jul 16 13:29 10MBnull


After applying the patch:

$ ls -lh 10MBnull 
-rw-r--r--  1 jaakko  jaakko    10M Jul 16 13:29 10MBnull
$ ls -lh /dev/null 10MBnull 
crw-rw-rw-  1 root    wheel     0,  26 Jul 16 13:33 /dev/null
-rw-r--r--  1 jaakko  jaakko       10M Jul 16 13:29 10MBnull

>Fix:

--- ls--h-with-device-files.diff begins here ---
Index: bin/ls/print.c
===================================================================
--- bin/ls/print.c	(revision 180487)
+++ bin/ls/print.c	(working copy)
@@ -65,7 +65,7 @@ static int	printaname(const FTSENT *, u_
 static void	printlink(const FTSENT *);
 static void	printtime(time_t);
 static int	printtype(u_int);
-static void	printsize(size_t, off_t);
+static void	printsize(size_t, off_t, int);
 #ifdef COLORLS
 static void	endcolor(int);
 static int	colortype(mode_t);
@@ -183,11 +183,8 @@ printlong(const DISPLAY *dp)
 			else
 				(void)printf("%3d, %3d ",
 				    major(sp->st_rdev), minor(sp->st_rdev));
-		else if (dp->bcfile)
-			(void)printf("%*s%*jd ",
-			    8 - dp->s_size, "", dp->s_size, sp->st_size);
 		else
-			printsize(dp->s_size, sp->st_size);
+			printsize(dp->s_size, sp->st_size, dp->bcfile);
 		if (f_accesstime)
 			printtime(sp->st_atime);
 		else if (f_birthtime)
@@ -599,7 +596,7 @@ printlink(const FTSENT *p)
 }
 
 static void
-printsize(size_t width, off_t bytes)
+printsize(size_t width, off_t bytes, int bcfile)
 {
 
 	if (f_humanval) {
@@ -607,8 +604,11 @@ printsize(size_t width, off_t bytes)
 
 		humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
 		    HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
-		(void)printf("%5s ", buf);
-	} else
+		(void)printf("%*s ", bcfile ? 8 : 5, buf);
+	} else if (bcfile)
+		(void)printf("%*s%*jd ",
+		    8 - (u_int)width, "", (u_int)width, bytes);
+	else
 		(void)printf("%*jd ", (u_int)width, bytes);
 }
 
--- ls--h-with-device-files.diff ends here ---


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->jh 
Responsible-Changed-By: jh 
Responsible-Changed-When: Fri Jan 8 08:04:41 UTC 2010 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=125678 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/125678: commit references a PR
Date: Sun, 24 Jan 2010 19:23:23 +0000 (UTC)

 Author: jh
 Date: Sun Jan 24 19:23:07 2010
 New Revision: 202945
 URL: http://svn.freebsd.org/changeset/base/202945
 
 Log:
   Fixes for ls(1) long format (-l) output:
   
   - Allow -h option to work if the listing contains at least one device
     file.
   - Align major and minor device numbers correctly to the size field.
   
   PR:		bin/125678
   Approved by:	trasz (mentor)
   MFC after:	1 month
 
 Modified:
   head/bin/ls/ls.c
   head/bin/ls/ls.h
   head/bin/ls/print.c
 
 Modified: head/bin/ls/ls.c
 ==============================================================================
 --- head/bin/ls/ls.c	Sun Jan 24 19:17:35 2010	(r202944)
 +++ head/bin/ls/ls.c	Sun Jan 24 19:23:07 2010	(r202945)
 @@ -559,7 +559,8 @@ display(const FTSENT *p, FTSENT *list, i
  	long maxblock;
  	u_long btotal, labelstrlen, maxinode, maxlen, maxnlink;
  	u_long maxlabelstr;
 -	int bcfile, maxflags;
 +	u_int devstrlen;
 +	int maxflags;
  	gid_t maxgroup;
  	uid_t maxuser;
  	size_t flen, ulen, glen;
 @@ -651,7 +652,7 @@ display(const FTSENT *p, FTSENT *list, i
  		MAKENINES(maxsize);
  		free(jinitmax);
  	}
 -	bcfile = 0;
 +	devstrlen = 0;
  	flags = NULL;
  	for (cur = list, entries = 0; cur; cur = cur->fts_link) {
  		if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
 @@ -791,9 +792,15 @@ label_out:
  				np->group = &np->data[ulen + 1];
  				(void)strcpy(np->group, group);
  
 -				if (S_ISCHR(sp->st_mode) ||
 -				    S_ISBLK(sp->st_mode))
 -					bcfile = 1;
 +				if ((S_ISCHR(sp->st_mode) ||
 +				    S_ISBLK(sp->st_mode)) &&
 +				    devstrlen < DEVSTR_HEX_LEN) {
 +					if (minor(sp->st_rdev) > 255 ||
 +					    minor(sp->st_rdev) < 0)
 +						devstrlen = DEVSTR_HEX_LEN;
 +					else
 +						devstrlen = DEVSTR_LEN;
 +				}
  
  				if (f_flags) {
  					np->flags = &np->data[ulen + glen + 2];
 @@ -825,7 +832,6 @@ label_out:
  	d.entries = entries;
  	d.maxlen = maxlen;
  	if (needstats) {
 -		d.bcfile = bcfile;
  		d.btotal = btotal;
  		(void)snprintf(buf, sizeof(buf), "%lu", maxblock);
  		d.s_block = strlen(buf);
 @@ -836,8 +842,14 @@ label_out:
  		d.s_inode = strlen(buf);
  		(void)snprintf(buf, sizeof(buf), "%lu", maxnlink);
  		d.s_nlink = strlen(buf);
 -		(void)snprintf(buf, sizeof(buf), "%ju", maxsize);
 -		d.s_size = strlen(buf);
 +		if (f_humanval)
 +			d.s_size = HUMANVALSTR_LEN;
 +		else {
 +			(void)snprintf(buf, sizeof(buf), "%ju", maxsize);
 +			d.s_size = strlen(buf);
 +		}
 +		if (d.s_size < devstrlen)
 +			d.s_size = devstrlen;
  		d.s_user = maxuser;
  	}
  	printfcn(&d);
 
 Modified: head/bin/ls/ls.h
 ==============================================================================
 --- head/bin/ls/ls.h	Sun Jan 24 19:17:35 2010	(r202944)
 +++ head/bin/ls/ls.h	Sun Jan 24 19:23:07 2010	(r202945)
 @@ -35,6 +35,10 @@
  
  #define NO_PRINT	1
  
 +#define HUMANVALSTR_LEN	5
 +#define DEVSTR_LEN	8
 +#define DEVSTR_HEX_LEN	15
 +
  extern long blocksize;		/* block size units */
  
  extern int f_accesstime;	/* use time of last access */
 @@ -62,7 +66,6 @@ extern int f_color;		/* add type in colo
  typedef struct {
  	FTSENT *list;
  	u_long btotal;
 -	int bcfile;
  	int entries;
  	int maxlen;
  	u_int s_block;
 
 Modified: head/bin/ls/print.c
 ==============================================================================
 --- head/bin/ls/print.c	Sun Jan 24 19:17:35 2010	(r202944)
 +++ head/bin/ls/print.c	Sun Jan 24 19:23:07 2010	(r202945)
 @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
  #include "extern.h"
  
  static int	printaname(const FTSENT *, u_long, u_long);
 +static void	printdev(size_t, dev_t);
  static void	printlink(const FTSENT *);
  static void	printtime(time_t);
  static int	printtype(u_int);
 @@ -165,16 +166,7 @@ printlong(const DISPLAY *dp)
  		if (f_label)
  			(void)printf("%-*s ", dp->s_label, np->label);
  		if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
 -			if (minor(sp->st_rdev) > 255 || minor(sp->st_rdev) < 0)
 -				(void)printf("%3d, 0x%08x ",
 -				    major(sp->st_rdev),
 -				    (u_int)minor(sp->st_rdev));
 -			else
 -				(void)printf("%3d, %3d ",
 -				    major(sp->st_rdev), minor(sp->st_rdev));
 -		else if (dp->bcfile)
 -			(void)printf("%*s%*jd ",
 -			    8 - dp->s_size, "", dp->s_size, sp->st_size);
 +			printdev(dp->s_size, sp->st_rdev);
  		else
  			printsize(dp->s_size, sp->st_size);
  		if (f_accesstime)
 @@ -353,6 +345,24 @@ printaname(const FTSENT *p, u_long inode
  	return (chcnt);
  }
  
 +/*
 + * Print device special file major and minor numbers.
 + */
 +static void
 +printdev(size_t width, dev_t dev)
 +{
 +	char buf[DEVSTR_HEX_LEN + 1];
 +
 +	if (minor(dev) > 255 || minor(dev) < 0)
 +		(void)snprintf(buf, sizeof(buf), "%3d, 0x%08x",
 +		    major(dev), (u_int)minor(dev));
 +	else
 +		(void)snprintf(buf, sizeof(buf), "%3d, %3d",
 +		    major(dev), minor(dev));
 +
 +	(void)printf("%*s ", (u_int)width, buf);
 +}
 +
  static void
  printtime(time_t ftime)
  {
 @@ -592,11 +602,15 @@ printsize(size_t width, off_t bytes)
  {
  
  	if (f_humanval) {
 -		char buf[5];
 +		/*
 +		 * Reserve one space before the size and allocate room for
 +		 * the trailing '\0'.
 +		 */
 +		char buf[HUMANVALSTR_LEN - 1 + 1];
  
  		humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
  		    HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
 -		(void)printf("%5s ", buf);
 +		(void)printf("%*s ", (u_int)width, buf);
  	} else
  		(void)printf("%*jd ", (u_int)width, bytes);
  }
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: jh 
State-Changed-When: Sun Jan 24 19:36:23 UTC 2010 
State-Changed-Why:  
Patched in head (r202945). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=125678 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/125678: commit references a PR
Date: Wed, 24 Feb 2010 15:27:51 +0000 (UTC)

 Author: jh
 Date: Wed Feb 24 15:27:31 2010
 New Revision: 204277
 URL: http://svn.freebsd.org/changeset/base/204277
 
 Log:
   MFC r202945:
   
   Fixes for ls(1) long format (-l) output:
   
   - Allow -h option to work if the listing contains at least one device
     file.
   - Align major and minor device numbers correctly to the size field.
   
   PR:		bin/125678
 
 Modified:
   stable/8/bin/ls/ls.c
   stable/8/bin/ls/ls.h
   stable/8/bin/ls/print.c
 Directory Properties:
   stable/8/bin/ls/   (props changed)
 
 Modified: stable/8/bin/ls/ls.c
 ==============================================================================
 --- stable/8/bin/ls/ls.c	Wed Feb 24 14:19:56 2010	(r204276)
 +++ stable/8/bin/ls/ls.c	Wed Feb 24 15:27:31 2010	(r204277)
 @@ -559,7 +559,8 @@ display(const FTSENT *p, FTSENT *list, i
  	long maxblock;
  	u_long btotal, labelstrlen, maxinode, maxlen, maxnlink;
  	u_long maxlabelstr;
 -	int bcfile, maxflags;
 +	u_int devstrlen;
 +	int maxflags;
  	gid_t maxgroup;
  	uid_t maxuser;
  	size_t flen, ulen, glen;
 @@ -651,7 +652,7 @@ display(const FTSENT *p, FTSENT *list, i
  		MAKENINES(maxsize);
  		free(jinitmax);
  	}
 -	bcfile = 0;
 +	devstrlen = 0;
  	flags = NULL;
  	for (cur = list, entries = 0; cur; cur = cur->fts_link) {
  		if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
 @@ -791,9 +792,15 @@ label_out:
  				np->group = &np->data[ulen + 1];
  				(void)strcpy(np->group, group);
  
 -				if (S_ISCHR(sp->st_mode) ||
 -				    S_ISBLK(sp->st_mode))
 -					bcfile = 1;
 +				if ((S_ISCHR(sp->st_mode) ||
 +				    S_ISBLK(sp->st_mode)) &&
 +				    devstrlen < DEVSTR_HEX_LEN) {
 +					if (minor(sp->st_rdev) > 255 ||
 +					    minor(sp->st_rdev) < 0)
 +						devstrlen = DEVSTR_HEX_LEN;
 +					else
 +						devstrlen = DEVSTR_LEN;
 +				}
  
  				if (f_flags) {
  					np->flags = &np->data[ulen + glen + 2];
 @@ -825,7 +832,6 @@ label_out:
  	d.entries = entries;
  	d.maxlen = maxlen;
  	if (needstats) {
 -		d.bcfile = bcfile;
  		d.btotal = btotal;
  		(void)snprintf(buf, sizeof(buf), "%lu", maxblock);
  		d.s_block = strlen(buf);
 @@ -836,8 +842,14 @@ label_out:
  		d.s_inode = strlen(buf);
  		(void)snprintf(buf, sizeof(buf), "%lu", maxnlink);
  		d.s_nlink = strlen(buf);
 -		(void)snprintf(buf, sizeof(buf), "%ju", maxsize);
 -		d.s_size = strlen(buf);
 +		if (f_humanval)
 +			d.s_size = HUMANVALSTR_LEN;
 +		else {
 +			(void)snprintf(buf, sizeof(buf), "%ju", maxsize);
 +			d.s_size = strlen(buf);
 +		}
 +		if (d.s_size < devstrlen)
 +			d.s_size = devstrlen;
  		d.s_user = maxuser;
  	}
  	printfcn(&d);
 
 Modified: stable/8/bin/ls/ls.h
 ==============================================================================
 --- stable/8/bin/ls/ls.h	Wed Feb 24 14:19:56 2010	(r204276)
 +++ stable/8/bin/ls/ls.h	Wed Feb 24 15:27:31 2010	(r204277)
 @@ -35,6 +35,10 @@
  
  #define NO_PRINT	1
  
 +#define HUMANVALSTR_LEN	5
 +#define DEVSTR_LEN	8
 +#define DEVSTR_HEX_LEN	15
 +
  extern long blocksize;		/* block size units */
  
  extern int f_accesstime;	/* use time of last access */
 @@ -62,7 +66,6 @@ extern int f_color;		/* add type in colo
  typedef struct {
  	FTSENT *list;
  	u_long btotal;
 -	int bcfile;
  	int entries;
  	int maxlen;
  	u_int s_block;
 
 Modified: stable/8/bin/ls/print.c
 ==============================================================================
 --- stable/8/bin/ls/print.c	Wed Feb 24 14:19:56 2010	(r204276)
 +++ stable/8/bin/ls/print.c	Wed Feb 24 15:27:31 2010	(r204277)
 @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
  #include "extern.h"
  
  static int	printaname(const FTSENT *, u_long, u_long);
 +static void	printdev(size_t, dev_t);
  static void	printlink(const FTSENT *);
  static void	printtime(time_t);
  static int	printtype(u_int);
 @@ -165,16 +166,7 @@ printlong(const DISPLAY *dp)
  		if (f_label)
  			(void)printf("%-*s ", dp->s_label, np->label);
  		if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
 -			if (minor(sp->st_rdev) > 255 || minor(sp->st_rdev) < 0)
 -				(void)printf("%3d, 0x%08x ",
 -				    major(sp->st_rdev),
 -				    (u_int)minor(sp->st_rdev));
 -			else
 -				(void)printf("%3d, %3d ",
 -				    major(sp->st_rdev), minor(sp->st_rdev));
 -		else if (dp->bcfile)
 -			(void)printf("%*s%*jd ",
 -			    8 - dp->s_size, "", dp->s_size, sp->st_size);
 +			printdev(dp->s_size, sp->st_rdev);
  		else
  			printsize(dp->s_size, sp->st_size);
  		if (f_accesstime)
 @@ -353,6 +345,24 @@ printaname(const FTSENT *p, u_long inode
  	return (chcnt);
  }
  
 +/*
 + * Print device special file major and minor numbers.
 + */
 +static void
 +printdev(size_t width, dev_t dev)
 +{
 +	char buf[DEVSTR_HEX_LEN + 1];
 +
 +	if (minor(dev) > 255 || minor(dev) < 0)
 +		(void)snprintf(buf, sizeof(buf), "%3d, 0x%08x",
 +		    major(dev), (u_int)minor(dev));
 +	else
 +		(void)snprintf(buf, sizeof(buf), "%3d, %3d",
 +		    major(dev), minor(dev));
 +
 +	(void)printf("%*s ", (u_int)width, buf);
 +}
 +
  static void
  printtime(time_t ftime)
  {
 @@ -592,11 +602,15 @@ printsize(size_t width, off_t bytes)
  {
  
  	if (f_humanval) {
 -		char buf[5];
 +		/*
 +		 * Reserve one space before the size and allocate room for
 +		 * the trailing '\0'.
 +		 */
 +		char buf[HUMANVALSTR_LEN - 1 + 1];
  
  		humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
  		    HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
 -		(void)printf("%5s ", buf);
 +		(void)printf("%*s ", (u_int)width, buf);
  	} else
  		(void)printf("%*jd ", (u_int)width, bytes);
  }
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: jh 
State-Changed-When: Wed Feb 24 15:37:53 UTC 2010 
State-Changed-Why:  
Fixed in head and stable/8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=125678 
>Unformatted:
