Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-05

FindFirst...FindClose

17 messages · 7 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Leonardo M. Ramé

Hi, I ported a Delphi service to linux using FPC. The app uses FindFirst, FindNext and FindClose the same way Delphi Help shows:

if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then
begin
  repeat
    ...
    ...
  until FindNext(sr)  0;
  FindClose(sr);
end;

Apparently my program gets stuck after a couple (several, in fact) of calls to the function that includes this code.

By reading the FPC.RTL documentation, I found it says that FindClose must be used outside the if, as follows:

if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then
begin
  repeat
    ...
    ...
  until FindNext(sr)  0;
end;
FindClose(sr);

Can be this the cause of the problem in my application?.

Thanks in advance.

Leonardo M. Ramé
http://leonardorame.blogspot.com

Jonas Maebe
to Leonardo M. Ramé
Leonardo M. Ramé wrote 16 lines
Apparently my program gets stuck after a couple (several, in fact) of calls to the function that includes this code. By reading the FPC.RTL documentation, I found it says that FindClose must be used outside the if, as follows: if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then begin repeat ... ... until FindNext(sr) 0; end; FindClose(sr); Can be this the cause of the problem in my application?.

Yes.

Jonas

Michael Van Canneyt
to Jonas Maebe
Jonas Maebe wrote 21 lines
On 18 May 2009, at 16:39, Leonardo M. Ramé wrote: >Apparently my program gets stuck after a couple (several, in fact) of calls >to the function that includes this code. > >By reading the FPC.RTL documentation, I found it says that FindClose must be >used outside the if, as follows: > >if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then >begin > repeat > ... > ... >until FindNext(sr) 0; >end; >FindClose(sr); > >Can be this the cause of the problem in my application?. Yes.

Huh ? Since when is this requirement ?

If it is correct, 100% of my FindFirst/FindClose code must be rewritten !

Michael.

Leonardo M. Ramé

You are not alone Michael, I also have to rewrite all of my FindFirst...FindClose calls :).

By reading the documentation a little more, I found that the unit OldLinux includes the Glob() function to search for files in Linux. This function returns a pointer that must be explicitly disposed by the GlobFree function, it doesn't matter if files where found or not.

I can't confirm this, but maybe FindFirst in linux is a wrapper to Glob, and that's why FindClose (in Linux) must be called outside the if.

Leonardo M. Ramé
http://leonardorame.blogspot.com

Michael Van Canneyt wrote 44 lines
From: Michael Van Canneyt Subject: Re: [fpc-pascal] FindFirst...FindClose To: "FPC-Pascal users discussions" Date: Monday, May 18, 2009, 12:25 PM On Mon, 18 May 2009, Jonas Maebe wrote: > > On 18 May 2009, at 16:39, Leonardo M. Ramé wrote: > > >Apparently my program gets stuck after a couple (several, in fact) of calls > >to the function that includes this code. > > > >By reading the FPC.RTL documentation, I found it says that FindClose must be > >used outside the if, as follows: > > > >if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then > >begin > > repeat > >   ... > >   ... > >until FindNext(sr) 0; > >end; > >FindClose(sr); > > > >Can be this the cause of the problem in my application?. > > Yes. Huh ? Since when is this requirement ? If it is correct, 100% of my FindFirst/FindClose code must be rewritten ! Michael. -----Inline Attachment Follows----- _______________________________________________ fpc-pascal maillist  -  http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Jonas Maebe
to Michael Van Canneyt: Huh ? Since when is this requirement ? If it is correct, 100% of my FindFirst/FindClose…
Michael Van Canneyt wrote 22 lines
On Mon, 18 May 2009, Jonas Maebe wrote: > On 18 May 2009, at 16:39, Leonardo M. Ramé wrote: > >> By reading the FPC.RTL documentation, I found it says that >> FindClose must be >> used outside the if, as follows: >> >> if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then >> begin >> repeat >> ... >> ... >> until FindNext(sr) 0; >> end; >> FindClose(sr); >> >> Can be this the cause of the problem in my application?. > > Yes. Huh ? Since when is this requirement ?

Since as long as I can remember. It at least predates the switch to svn (revision 1 of both rtl/unix/dos.pp and of rtl/unix/sysutils.pp requires it).

Jonas

Michael Van Canneyt
to Jonas Maebe
Jonas Maebe wrote 28 lines
On 18 May 2009, at 17:25, Michael Van Canneyt wrote: > On Mon, 18 May 2009, Jonas Maebe wrote: > >> On 18 May 2009, at 16:39, Leonardo M. Ramé wrote: >> >>> By reading the FPC.RTL documentation, I found it says that FindClose must >>> be >>> used outside the if, as follows: >>> >>> if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then >>> begin >>> repeat >>> ... >>> ... >>> until FindNext(sr) 0; >>> end; >>> FindClose(sr); >>> >>> Can be this the cause of the problem in my application?. >> >> Yes. > > Huh ? Since when is this requirement ? Since as long as I can remember. It at least predates the switch to svn (revision 1 of both rtl/unix/dos.pp and of rtl/unix/sysutils.pp requires it).

As far as I know, the FindClose is only needed when FindFirst returned zero. At least, that's what you can deduce from MSDN, and this is how I programmed it since ages.

Michael.

Unknown author
to Michael Van Canneyt: Huh ? Since when is this requirement ? If it is correct, 100% of my FindFirst/FindClose…

I must agree with Michael.

In my experience, it doesn't matter where the findclose() is placed, as long as it's called within the scope of the findfirst(), findnext(). If findclose() is not called, all that happens is that the OS will use up file handles, which are finite in quantity on any given system.

If you're using Delphi or FPC in MS Windows, fire up Task Manager, check the "Handles" column within the "processes" tab in task manager to see if handles are being "lost" from within your app.

BTW, Task manager is a simple debugging "tool" that helps identify how your app is doing with regards to a range of resources, memory, etc. I also use KDE System Guard when coding for Linux.

:=Nino
//*****************************************************************************************************
Michael Van Canneyt wrote 26 lines
On Mon, 18 May 2009, Jonas Maebe wrote: > On 18 May 2009, at 16:39, Leonardo M. Ramé wrote: > >Apparently my program gets stuck after a couple (several, in fact) of > > calls to the function that includes this code. > > > >By reading the FPC.RTL documentation, I found it says that FindClose > > must be used outside the if, as follows: > > > >if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then > >begin > > repeat > > ... > > ... > >until FindNext(sr) 0; > >end; > >FindClose(sr); > > > >Can be this the cause of the problem in my application?. > > Yes. Huh ? Since when is this requirement ? If it is correct, 100% of my FindFirst/FindClose code must be rewritten ! Michael.
Marco van de Voort
to Jonas Maebe: Since as long as I can remember. It at least predates the switch to svn (revision 1 of…

In our previous episode, Jonas Maebe said:

Show quoted text 8 lines
>> >> Yes. > > Huh ? Since when is this requirement ? Since as long as I can remember. It at least predates the switch to svn (revision 1 of both rtl/unix/dos.pp and of rtl/unix/sysutils.pp requires it).

The current situation is probably simply the old "linux" unit routines folded into sysutils. The fact that it is documented that way probably makes it more than likely it was no mistake.

Michael Van Canneyt
to Marco van de Voort: In our previous episode, Jonas Maebe said: The current situation is probably simply the…
Marco van de Voort wrote 13 lines
In our previous episode, Jonas Maebe said: >>> >>> Yes. >> >> Huh ? Since when is this requirement ? > > Since as long as I can remember. It at least predates the switch to > svn (revision 1 of both rtl/unix/dos.pp and of rtl/unix/sysutils.pp > requires it). The current situation is probably simply the old "linux" unit routines folded into sysutils. The fact that it is documented that way probably makes it more than likely it was no mistake.

Given that I documented it, I'd rather say that I was sloppy in the formulation. I've always assumed that the findclose was only needed in case of a _succesful_ findfirst, i.e. one that returns 0. And I've seen a lot of code that assumes the same (admittedly, it was Win32 code).

Once more, if this is so, there is a lot of code that needs to be checked in FPC. It might be easier to "fix" findfirst so that in case of an error (nonzero return value), the searchrec record is cleared, and the findclose() call is redundant.

I checked the windows code, and FindClose explicitly checks that the searchrec record contains a valid handle (i.e. NOT INVALID_HANDLE_VALUE), so all platforms would behave the same.

Opinions ? If no-one objects, I'll implement the 'fix', it's only 2 lines of code.

Michael.

Leonardo M. Ramé

This sounds good, just also check what happens if FindClose receives an invalid handle.

Leonardo M. Ramé
http://leonardorame.blogspot.com

Michael Van Canneyt wrote 59 lines
From: Michael Van Canneyt Subject: Re: [fpc-pascal] FindFirst...FindClose To: "FPC-Pascal users discussions" Date: Monday, May 18, 2009, 4:03 PM On Mon, 18 May 2009, Marco van de Voort wrote: > In our previous episode, Jonas Maebe said: >>>> >>>> Yes. >>> >>> Huh ? Since when is this requirement ? >> >> Since as long as I can remember. It at least predates the switch to >> svn (revision 1 of both rtl/unix/dos.pp and of rtl/unix/sysutils.pp >> requires it). > > The current situation is probably simply the old "linux" unit routines > folded into sysutils. The fact that it is documented that way probably makes > it more than likely it was no mistake. Given that I documented it, I'd rather say that I was sloppy in the formulation. I've always assumed that the findclose was only needed in case of a _succesful_ findfirst, i.e. one that returns 0. And I've seen a lot of code that assumes the same (admittedly, it was Win32 code). Once more, if this is so, there is a lot of code that needs to be checked in FPC. It might be easier to "fix" findfirst so that in case of an error (nonzero return value), the searchrec record is cleared, and the findclose() call is redundant. I checked the windows code, and FindClose explicitly checks that the searchrec record contains a valid handle (i.e. NOT INVALID_HANDLE_VALUE), so all platforms would behave the same. Opinions ? If no-one objects, I'll implement the 'fix', it's only 2 lines of code. Michael. _______________________________________________ fpc-pascal maillist  -  http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Michael Van Canneyt
to Leonardo M. Ramé
Leonardo M. Ramé wrote
This sounds good, just also check what happens if FindClose receives an invalid handle.

That was the second line in my line count estimate ;-)

Michael.

Michael Van Canneyt
to Marco van de Voort: In our previous episode, Michael Van Canneyt said: No fundamental objections, but maybe…
Marco van de Voort wrote 7 lines
In our previous episode, Michael Van Canneyt said: > Opinions ? If no-one objects, I'll implement the 'fix', it's only > 2 lines of code. No fundamental objections, but maybe wait till just before a release to avoid packages that work with both 2.2.4 and 2.3.1 having to ifdef till the next release?

There will be no need for an ifdef. All code will continue to work as-is. Only memory leaks that now may exist will be solved.

Michael.

Tomas Hajny
to Jonas Maebe
Jonas Maebe wrote 10 lines
On 18 May 2009, at 21:03, Michael Van Canneyt wrote: > I checked the windows code, and FindClose explicitly checks that > the searchrec record contains a valid handle (i.e. NOT > INVALID_HANDLE_VALUE), so all platforms would behave the same. > > Opinions ? If no-one objects, I'll implement the 'fix', it's only > 2 lines of code. It's fine by me.

No problem here either, just make sure that you check whether SysUtils.FindFirst and Dos.FindFirst are consistent in this context (i.e. probably more than two lines of code are necessary even if disregarding any other platforms out there apart from Unix ;-) ).

Tomas