/bin/ls -C Question (my fix with context diff)

Sean Casey sean at ukma.UUCP
Sun Feb 23 12:32:45 AEST 1986


In article <337 at chinet.UUCP> megabyte at chinet.UUCP (Mark E. Sunderlin) writes:
>Ok, here is my question to the net.  Why does ls -C Sometimes
>NOT print across the screen?  Most of the time when I enter
>a ls -C I get a nice diretory like:
>News    fvps.c  h19     mbox    vps.c
>But some times a directory will list one per line on me.  What does
>ls make this decision on?  I have seen this behavior on both at&t 3b2
>machines and on Tandy 6000 machines. (sys V on one Xenix 3 on the latter)
>Any thoughts???

The problem is an oversight in the design.  The structure that the file
name is being read into is exactly large enough to hold the file name
and no more (14 chars).  If the filename is less than 14 characters long,
there is a null terminator.  If the file name is exactly 14 characters
long (the maximum), there is no null terminator because there is no room
for one.

This causes problems when ls attempts to determine how many columns it can
put on the screen.  Since the filename isn't null terminated, when ls
does a strlen() to see how long the filename is, it not only looks at
the 14 characters of the filename, but at any junk after that until it
happens to hits a null.  Thus, when you have a filename of 14 characters,
ls incorrectly thinks that you have a VERY long filename.  It divides the
screen width by the width of the largest file to determine how many columns
can go on the screen.  Since you now have a BIG filename, it goes "gee, I
can only put one column of files on the screen".

The easiest fix is to make sure that no filename is ever regarded as being
longer than the longest you're allowed to have.  Context diff follows:

-------- CUT HERE -------- CUT HERE --------
*** ls.c.old	Sat Feb 22 21:12:36 1986
--- ls.c	Sat Feb 22 21:13:05 1986
***************
*** 616,621
            			continue;
  			if (Cflg || mflg) {
  				width = strlen(dentry.d_name);
  				if (width > filewidth)
  					filewidth = width;
  			}

--- 616,632 -----
            			continue;
  			if (Cflg || mflg) {
  				width = strlen(dentry.d_name);
+ 
+ /*	CHANGE	[10-Feb-86 sean at ukma]	ls -C fix
+  *
+  *	If a file name is the maximum size (DIRSIZ), then dentry.d_name will
+  *	not have a null terminator.  This causes width to be set too high and
+  *	the files will print in reduced columns. The fix is to check the width
+  *	and set it to DIRSIZ if it exceeds DIRSIZ.
+  */
+ 				if (width > DIRSIZ)
+ 					width = DIRSIZ;
+ 
  				if (width > filewidth)
  					filewidth = width;
  			}
-------- CUT HERE -------- CUT HERE --------


What I don't understand is that later on in the program, they force a null
into the filename at the proper point so that it can be printed out.  It
seems to me that if whoever wrote it did this then they would also see the
need for the null here.

Sean



-- 
-------------------------------------------------------------------------------
Sean Casey                UUCP:  sean at ukma.uucp          CSNET:  sean at uky.csnet
University of Kentucky    ARPA:  ukma!sean at anl-mcs.arpa
Lexington, Kentucky     BITNET:  sean at ukma.bitnet

     "Remember, no matter where you go, there you are."	 - BB



More information about the Comp.unix mailing list