[comp.os.msdos.programmer] Bug in TC findfirst

Rick_Vandenberg@mindlink.UUCP (Rick Vandenberg) (02/25/91)

> gordon@osiris.cso.uiuc.edu writes:
> 
>         According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
> are supposed to return filenames that match *both* the given path *and* the
> given attribute.  However, the above program, which clearly specifies the
> *directory* attribute (FA_DIREC), finds both directories *and* plain files.
> Anyone have any comments/fixes/etc?
> 
> 


This is not a bug. The DOS calls for Search for first / next match work the
same way. You might find it helpful to get a book along the lines of the DOS
Programmers Reference, that documents each interrupt.
By the way, the attribute for normal files in 0x00. Because no bits are set,
these calls will always match normal files.

Rick.
--
Rick Vandenberg                Rick_Vandenberg@Mindlink.UUCP
Vandenberg Systems Research    uunet!van-bc!rsoft!mindlink!Rick_Vandenberg

gordon@osiris.cso.uiuc.edu (John Gordon) (02/26/91)

	I submit the following program:

----------
#include <stdio.h>
#include <string.h>
#include <dir.h>
#include <dos.h>
#include <io.h>

main()
{
  struct ffblk fileinfo;
  char path[256];

  getcwd(path, 250);

  strcat(path, "\\*.*");

  if(findfirst(path, &fileinfo, FA_DIREC) != 0) /* scan for subdirs */
  {
    printf("No sub-directories!\n");
    exit(2);
  }

  printf("%s\n", fileinfo.ff_name);

  while(findnext(&fileinfo) == 0) /* continue scanning for subdirs */
    printf("%s\n", fileinfo.ff_name);

}
---------

	According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
are supposed to return filenames that match *both* the given path *and* the
given attribute.  However, the above program, which clearly specifies the
*directory* attribute (FA_DIREC), finds both directories *and* plain files.
Anyone have any comments/fixes/etc?


---
John Gordon
Internet: gordon@osiris.cso.uiuc.edu        #include <disclaimer.h>
          gordon@cerl.cecer.army.mil       #include <clever_saying.h>

bwilliam%peruvian.utah.edu@cs.utah.edu (Bruce R. Williams) (02/26/91)

In article <1991Feb25.192823.18224@ux1.cso.uiuc.edu> gordon@osiris.cso.uiuc.edu (John Gordon) writes:
>
>	I submit the following program:
  ...

>	According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
>are supposed to return filenames that match *both* the given path *and* the
>given attribute.  However, the above program, which clearly specifies the
>*directory* attribute (FA_DIREC), finds both directories *and* plain files.
>Anyone have any comments/fixes/etc?

>John Gordon
>Internet: gordon@osiris.cso.uiuc.edu        #include <disclaimer.h>
>          gordon@cerl.cecer.army.mil       #include <clever_saying.h>


  Having just written a "new and improved" dir, I came across the same
behavior.  Fortunately, it only occurs in this one case--using the FA_DIREC
attrib alone.  One way around it would be to make a change like:

  while(findnext(&fileinfo) == 0) /* continue scanning for subdirs */
    if (fileinfo.ff_attrib == FA_DIREC)
      printf("%s\n", fileinfo.ff_name);

One other change you'll be wanting to make in your code:  The result of
getcwd() already ends with \ if you are in the root directory.  So..

  getcwd(path, 250);
  if (path[strlen(path)-1] == '\\')
    strcat(path, "*.*");
  else
    strcat(path, "\\*.*");

Good Luck!

-Bruce

Bruce R. Williams                "The most beautiful thing we can experience
University of Utah                is the mysterious.  It is the source of all
(bwilliam@peruvian.utah.edu)      true art and science."  -Albert Einstein

suhonen@kunto.jyu.fi (Timo Suhonen) (02/26/91)

gordon@osiris.cso.uiuc.edu (John Gordon) writes:

	   I submit the following program:

[program removed]

   According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
   are supposed to return filenames that match *both* the given path *and* the
   given attribute.  However, the above program, which clearly specifies the
   *directory* attribute (FA_DIREC), finds both directories *and* plain files.
   Anyone have any comments/fixes/etc?

Find out what is this directory attribute (FA_DIRECT)!!! I have used 
findfirst() and findnext() with TC 1.5, 2.0 and TC++ 1.00 with no
problems. BUT I have defined myself the directory attribute (was it 0x10?).

I'll look my code at home next night...

--
Timo Suhonen        I am logged in, therefore I am        suhonen@nic.funet.fi
                                                          suhonen@kunto.jyu.fi
   Opinions(?) are mine (if not stolen), NOT those of Univ. of Jyvaskyla.

anto@vaxb.acs.unt.edu (02/26/91)

In article <1991Feb25.192823.18224@ux1.cso.uiuc.edu>, 
gordon@osiris.cso.uiuc.edu (John Gordon) writes:
> 
> 	I submit the following program:
> 
> ----------

[... code deleted ...]

> 	According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
> are supposed to return filenames that match *both* the given path *and* the
> given attribute.  However, the above program, which clearly specifies the
> *directory* attribute (FA_DIREC), finds both directories *and* plain files.
> Anyone have any comments/fixes/etc?

The TC manual entry for findfirst tells me to check the DOS manual, so I did.
MS-DOS Encyclopedia has the following for INT 21h Func 4Eh (Find First File):

...
The attribute word in CX controls the search as follows:
- If the attribute word os 00H, only normal files are included in the search.
- If the attribute word has any combination of bits 1, 2, and 4 (hidden, sys-
  tem, and subdirectory bits) set, the search includes NORMAL FILES as well as
  files with any of the attributes specified. [Emphasis mine]
- If the attribute word has bit 3 set (volume-label bit), only a matching 
  volume label is returned.
- Bits 0 and 5 (read-only and archive bits) are ignored by Function 4EH.
...

I hope this clears up any confusions.

> John Gordon
> Internet: gordon@osiris.cso.uiuc.edu        #include <disclaimer.h>
>           gordon@cerl.cecer.army.mil       #include <clever_saying.h>

Regards,

Anto.

stoeen@solan.unit.no (Asbj|rn St|en) (02/27/91)

In article <1991Feb25.192823.18224@ux1.cso.uiuc.edu>, gordon@osiris.cso.uiuc.edu (John Gordon) writes:
|> 	According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
|> are supposed to return filenames that match *both* the given path *and* the
|> given attribute.  However, the above program, which clearly specifies the
|> *directory* attribute (FA_DIREC), finds both directories *and* plain files.
|> Anyone have any comments/fixes/etc?

This is not a bug in TC, but the way DOS handles findfirst() and
findnext(). DOS always returns plain files, *plus* the files that
matches the given attribute. This is the way find..() works in other
languages, so it can't be changed in TC. The _Turbo_C_Bible_ is
probably inaccurate here.

You will always have to check the attribute (0 = plain file).
-- 
			_
Asbjoern Stoeen	       / \     /___
Studpost 188          /___\   //
7034 Trondheim-NTH   / 	   \ / \__
Norway		    	    /     \
(stoeen@solan.unit.no)     /   ___/
	

Nathan.Torkington@comp.vuw.ac.nz (Nathan Torkington) (02/27/91)

In article <1991Feb25.192823.18224@ux1.cso.uiuc.edu> gordon@osiris.cso.uiuc.edu (John Gordon) writes:

	[program]
   ---------

	   According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
   are supposed to return filenames that match *both* the given path *and* the
   given attribute.  However, the above program, which clearly specifies the
   *directory* attribute (FA_DIREC), finds both directories *and* plain files.
   Anyone have any comments/fixes/etc?

I found this too, attempting to write a ls for the PC.  You have to check the
directory attribute yourself in the ffblk.  What a pain that is.  I wrote a
	natFindFirst(...) and
	natFindNext(...)
which did the checking of attributes manually and findnexted until it got a
match or end.  Obvious, clumsy and uncouth.  You could always rewrite the
library.

Nat.
--
[  death@comp.vuw.ac.nz aka Blackadder@st1.vuw.ac.nz aka Nathan Torkington  ]
[ death dies soon.  Instead use gnat@rata.vuw.ac.nz which is less transient ]
[ "Graeme Lee ... a condom on the penis of progress"            - Bob Jones ]
[ This is not an official communication of Victoria University, Wellington. ]

abcscnuk@csunb.csun.edu (Naoto Kimura (ACM)) (02/28/91)

In article <DEATH.91Feb26102938@kaukau.comp.vuw.ac.nz> Nathan.Torkington@comp.vuw.ac.nz (Nathan Torkington) writes:
]In article <1991Feb25.192823.18224@ux1.cso.uiuc.edu> gordon@osiris.cso.uiuc.edu (John Gordon) writes:
]
] ... (text deleted) ...
] ... (description of problem: findfirst and findnext match regular
]      files, even though only the FA_DIREC attribute is selected) ...
]

If I'm not mistaken, this is because DOS performs this way !  I ran
across this problem when implementing a findfirst and findnext
procedure for Turbo Pascal (v 3.0).

Other strange things that occurr because of quirks in DOS.  Using TYPE
and I/O redirection to print a file to a serial port printer fails
miserably (you end up getting a "Printer out of paper error" whenever
the printer signals that its buffer is full), while using the COPY
command to copy to the printer works fine.

                //-n-\\			 Naoto Kimura
        _____---=======---_____		 (abcscnuk@csuna.csun.edu)
    ====____\   /.. ..\   /____====
  //         ---\__O__/---         \\	Enterprise... Surrender or we'll
  \_\                             /_/	send back your *&^$% tribbles !!

barbourj@mozart.cs.colostate.edu (jim barbour) (02/28/91)

>In article <1991Feb25.192823.18224@ux1.cso.uiuc.edu> gordon@osiris.cso.uiuc.edu (John Gordon) writes:
>
>	I submit the following program:
>  ...
>
>	According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
> are supposed to return filenames that match *both* the given path *and* the
> given attribute.  However, the above program, which clearly specifies the
> *directory* attribute (FA_DIREC), finds both directories *and* plain files.
> Anyone have any comments/fixes/etc?
>
> John Gordon
> Internet: gordon@osiris.cso.uiuc.edu        #include <disclaimer.h>
>           gordon@cerl.cecer.army.mil       #include <clever_saying.h>

The Turbo C Bible is wrong, i.e. its a documentation error, not a bug.

Unfortunately, my TC++ manual doesn't document this "feature" very well either.

My TC++ manual says something to the effect that findfirst uses dos function
$4E to look up files.  It also says something like "for more information about
the attr field, see your dos manual."

The New Peter Norton Programming Guide to the IBM PC and PS/2 says about dos
function $4E:

"The attribute search follows a certain logic.  If you specify any combination
of the hidden, system and directory attributes bits, the search matches all
normal files, plus any files matching the specified attributes."

My Turbo Pascal 5.5 manual says "The Attr parameter specifies the special
files to include (in addition to all normal files.)"

I find this kind of documentation shortfall on Borland's part often.  It the
one biggest complaint I have again Borland.  I've never seen the Turbo C
Bible, so I don't know if it has as many omissions.

Jim Barbour (jwbarbour@clipr.colorado.edu)

bei@dogface (Bob Izenberg) (03/01/91)

gordon@osiris.cso.uiuc.edu (John Gordon) writes:

> 	According to the _Turbo_C_Bible_, calls to findfirst() and findnext()
> are supposed to return filenames that match *both* the given path *and* the
> given attribute.  However, the above program, which clearly specifies the
> *directory* attribute (FA_DIREC), finds both directories *and* plain files.
> Anyone have any comments/fixes/etc?

It's exhibiting the same behavior that the DOS function calls do.  Try it in
assembler and you'll have the same experience.
IMHO, this is an instance in which Borland might have improved upon DOS a bit.
A Microsoft purist could mouth the reason for the way this was implemented.
I'll reserve judgment, and re-check the "directory" matches.
-- Bob