delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1996/04/14/08:45:14

Date: Sun, 14 Apr 1996 15:43:43 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: djgpp-workers AT delorie DOT com
Subject: Re: Numbers of links for directories
In-Reply-To: <Pine.SUN.3.91.960411120247.27524V-100000@is>
Message-Id: <Pine.SUN.3.91.960414153955.2679D-100000@is>
Mime-Version: 1.0

On Thu, 11 Apr 1996, I wrote:

> Under Unix, the number of links for a directory is equal to the number of 
> its subdirectories plus 2.  Our `stat' always reports 1 in this field.  
> If people think that it's worthwhile to add such a feature, it is very 
> easy to do: `stat' already finds all the subdirectories to report 
> non-zero size for a directory.  So far I only saw this used by GNU 
> Findutils during a recursive descent, to know there is no more 
> subdirectories left, and the gain from using this didn't seem to be a 
> large one, but since compatibility is the name of the game here...

I take my words back.  It seems that I did something wrong while measuring
the effect of adding the above feature, because it actually makes `find'
much faster (by a factor of 2 to 4).  So here is a simple patch that 
teaches `stat' to return a link count for directories:

*** posix/sys/stat/stat.c~3	Sat Apr  6 13:20:20 1996
--- posix/sys/stat/stat.c	Sat Apr 13 22:23:08 1996
*************** almost_done:
*** 723,728 ****
--- 723,733 ----
           the disk pool.  Still, it is a good approximation of the
           actual directory size.
  
+          We also take this opportunity to return the number of links
+          for directories as Unix programs expect it to be: the number
+          of subdirectories, plus 2 (the directory itself and the ``.''
+          entry).
+ 
           The (max) size of the root directory could also be taken from
           the disk BIOS Parameter Block (BPB) which can be obtained
           by calling IOCTL (INT 21/AH=44H), subfunction 0DH, minor
*************** almost_done:
*** 741,754 ****
        else
          strcat(search_spec, "\\*.*");
  
        if (!__findfirst(search_spec, &ff_blk, ALL_FILES))
!         for (i = 1; !__findnext(&ff_blk); ++i)
!           ;
  
        /* In non-root directories, don't count the ``.'' and ``..''
!          entries, so that empty directories will be shown as such.  */
        if (statbuf->st_ino != 1)
!         i -= 2;
  
        statbuf->st_size = i * sizeof(struct full_dirent);
      }
--- 746,774 ----
        else
          strcat(search_spec, "\\*.*");
  
+       /* For the root directories we sumulate the missing
+          ``.'' entry so that root won't be special.  */
+       if (statbuf->st_ino == 1)
+         statbuf->st_nlink = 2;
+ 
        if (!__findfirst(search_spec, &ff_blk, ALL_FILES))
!         {
!           statbuf->st_nlink++;
!           for (i = 1; !__findnext(&ff_blk); ++i)
!             if (ff_blk.ff_attrib & 0x10)
!               statbuf->st_nlink++;
!         }
  
        /* In non-root directories, don't count the ``.'' and ``..''
!          entries when computing the size, so that empty directories
!          will be shown as such.  The ``..'' entry shouldn't be
!          counted for the st_nlink purposes, therefore we subtract
!          1 from the result of the above loop.  */
        if (statbuf->st_ino != 1)
!         {
!           i -= 2;
!           statbuf->st_nlink--;
!         }
  
        statbuf->st_size = i * sizeof(struct full_dirent);
      }


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019