[fpc-pascal] RE: findfirst and findnext on non accessible files
Marc Santhoff
M.Santhoff at t-online.de
Thu Jun 29 00:19:40 CEST 2006
Am Donnerstag, den 29.06.2006, 00:04 +0200 schrieb Michael Van Canneyt:
>
> On Wed, 28 Jun 2006, Marc Santhoff wrote:
>
> > Am Mittwoch, den 28.06.2006, 12:17 -0500 schrieb Jeff Pohlmeyer:
> > > If I remember correctly, the DOS FindFirst/Next only handles
> > > shortstring-sized path names.
> >
> > If possible at all I will not use DOS unit.
> >
> > > Another "quirk" about using FindNext on Unix is that a
> > > symlink to a directory sets the faDirectory flag, and if it
> > > happens to be a circular symlink, I don't know of any
> > > way tell if it is safe to recurse into it without using fpStat
> > > or something like it. FindNext will eventually give up after
> > > several loops, but that doesn't seem like a very
> > > elegant way to handle the situation.
> >
> > This should be no problem in principle, since the unix syscalls detect
> > this state and fail (according to Stevens[1]). But relying on the system
> > working properly is no good policy ...
>
> IMHO:
> On the contrary. If you can't trust the system, then what can you trust ?
Oaky, i can accept this as a guideline for viewing fpc's internals.
> > What I don't understand is why the var "errno" is not set or it's value
> > is destroyed before Findfirst/-Next return. Does this value has to be
> > set explicitely by using fpseterrno()? It returns always -1 in case of
> > permission denied.
>
> You should not ever rely on SysUtils setting errno.
> Errno is a variable used in the Unix subsystem.
> It is only valid to check errno when directly executing calls from the
> baseunix,unix calls.
>
> SysUtils calls may or may not destroy this value, but you should not rely on this.
My approach to detect failing FindFirst/FindNext would be to do
something like this:
<--- rtl/unix/sysutils.pp:549 --->
Function GlobToTSearchRec (Var Info : TSearchRec) : Boolean;
Var SInfo : Stat;
p : Pglob;
GlobSearchRec : PGlobSearchrec;
begin
GlobSearchRec:=Info.FindHandle;
P:=GlobSearchRec^.GlobHandle;
Result:=P<>Nil;
If Result then
begin
GlobSearchRec^.GlobHandle:=P^.Next;
Result:=Fpstat(GlobSearchRec^.Path+StrPas(p^.name),SInfo)>=0;
+ if NOT Result then
+ begin
+ fpseterrno(??? anything "legal" representing the system error);
+ end;
Info.PathOnly:=GlobSearchRec^.Path;
If Result then
</--->
I'd appreciate hints on doing it this way (getting system error number
by "fpgetCerrno()"?) or some better technique.
If the errno variants are not reliable it could be done by
1. using an additional out-parameter value
2. changing the result from boolean to interger or longint returning the
error number
But both methods would break old code.
Marc
More information about the fpc-pascal
mailing list