ref: 0cd2ccb2e2bc82eba1dc0a56c287f66a91fa1329
parent: 637632627d9eac3035ac0d9f07f252ab4a10ae71
author: Konstantinn Bonnet <qu7uux@gmail.com>
date: Fri Mar 27 09:36:06 EDT 2015
fix botched Sys_FindFirst, Sys_FindNext a dirread(2) call populates a Dir array with successive reads of the directory, while dirreadall(2) reads in the entire directory - but the end result of either call is a Dir array containing all entries. (e.g. you don't read one dir entry at a time with dirread())
--- a/plan9/q_sh9.c
+++ b/plan9/q_sh9.c
@@ -8,8 +8,8 @@
int curhunksize;
int curtime;
char findbase[MAX_OSPATH], findpath[MAX_OSPATH], findpattern[MAX_OSPATH];
-int fdir = -1;
-Dir *ddir;
+long dirn, di;
+Dir *dirs;
int glob_match(char *, char *);
@@ -172,6 +172,7 @@
return 0;
}
+ /* if the pattern is empty, Sys_FindNext looks at the current file anyway */
return *t == '\0';
}
@@ -231,11 +232,11 @@
close(d);
}
-qboolean CompareAttributes (Dir *d, uint musthave, uint canthave)
+qboolean CompareAttributes (ulong m, uint musthave, uint canthave)
{
- if(d->mode & DMDIR && canthave & SFF_SUBDIR)
+ if(m & DMDIR && canthave & SFF_SUBDIR)
return false;
- if(musthave & SFF_SUBDIR && ~d->mode & DMDIR)
+ if(musthave & SFF_SUBDIR && ~m & DMDIR)
return false;
return true;
}
@@ -243,9 +244,9 @@
char *Sys_FindFirst (char *path, uint musthave, uint canhave)
{
char *p;
- long n;
+ int fd;
- if(fdir != -1)
+ if(dirs != nil)
Sys_Error("Sys_BeginFind without close");
strncpy(findbase, path, sizeof findbase-1);
@@ -261,50 +262,46 @@
return nil;
}
- if((fdir = open(findbase, OREAD)) < 0){
+ if((fd = open(findbase, OREAD)) < 0){
fprint(2, "Sys_BeginFind:open: %r\n");
return nil;
}
-
- while((n = dirread(fdir, &ddir)) > 0){
- if(glob_match(findpattern, ddir->name)){
- if(CompareAttributes(ddir, musthave, canhave)){
- sprintf(findpath, "%s/%s", findbase, ddir->name);
- return findpath;
- }
- }
- }
- if(n < 0)
+ dirn = dirreadall(fd, &dirs);
+ close(fd);
+ if(dirn == 0)
+ return nil;
+ if(dirn < 0){
fprint(2, "Sys_BeginFind:dirread: %r\n");
- return nil;
+ return nil;
+ }
+
+ di = 0;
+ return Sys_FindNext (musthave, canhave);
}
char *Sys_FindNext (uint musthave, uint canhave)
{
- long n;
+ int i;
- if(fdir == -1){
+ if(dirs == nil)
Sys_Error("Sys_FindNext without open\n");
- return nil;
- }
- while((n = dirread(fdir, &ddir)) > 0){
- if(glob_match(findpattern, ddir->name)){
- if(CompareAttributes(ddir, musthave, canhave)){
- sprintf(findpath, "%s/%s", findbase, ddir->name);
+
+ while(di < dirn){
+ i = di++;
+ if(glob_match(findpattern, dirs[i].name)){
+ if(CompareAttributes(dirs[i].mode, musthave, canhave)){
+ snprintf(findpath, sizeof findpath, "%s/%s", findbase, dirs[i].name);
return findpath;
}
}
}
- if(n < 0)
- fprint(2, "Sys_BeginFind:dirread: %r\n");
return nil;
}
void Sys_FindClose (void)
{
- if(fdir != -1){
- close(fdir);
- free(ddir);
- fdir = -1;
+ if(dirs != nil){
+ free(dirs);
+ dirs = nil;
}
}