Date: Sun, 14 Apr 1996 15:43:43 +0200 (IST) From: Eli Zaretskii To: djgpp-workers AT delorie DOT com Subject: Re: Numbers of links for directories In-Reply-To: Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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); }