loader: walk directory paths with readdir(), don't stat() everything

Walk the directories with readdir, and don't stat everything we can
find.  Thanks to davej for the public humiliation reminding me to go back
and re-fix this one.
This commit is contained in:
Daniel Stone 2006-07-21 19:57:28 -04:00 committed by Daniel Stone
parent 63dfaa1d5b
commit 6cf844ab69

View File

@ -389,23 +389,65 @@ FreeSubdirs(const char **subdirs)
} }
static char * static char *
FindModule(const char *module, const char *dir, const char **subdirlist, FindModuleInSubdir(const char *dirpath, const char *module)
{
struct dirent *direntry = NULL;
DIR *dir = NULL;
char *ret = NULL, tmpBuf[PATH_MAX];
struct stat stat_buf;
dir = opendir(dirpath);
if (!dir)
return NULL;
while ((direntry = readdir(dir))) {
if (direntry->d_name[0] == '.')
continue;
if ((stat(direntry->d_name, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
snprintf(tmpBuf, PATH_MAX, "%s/%s", dirpath, direntry->d_name);
if ((ret = FindModuleInSubdir(tmpBuf, module)))
break;
continue;
}
snprintf(tmpBuf, PATH_MAX, "lib%s.so", module);
if (strcmp(direntry->d_name, tmpBuf) == 0) {
ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
sprintf(ret, "%s/%s", dirpath, tmpBuf);
break;
}
snprintf(tmpBuf, PATH_MAX, "%s_drv.so", module);
if (strcmp(direntry->d_name, tmpBuf) == 0) {
ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
sprintf(ret, "%s/%s", dirpath, tmpBuf);
break;
}
snprintf(tmpBuf, PATH_MAX, "%s.so", module);
if (strcmp(direntry->d_name, tmpBuf) == 0) {
ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
sprintf(ret, "%s/%s", dirpath, tmpBuf);
break;
}
}
closedir(dir);
return ret;
}
static char *
FindModule(const char *module, const char *dirname, const char **subdirlist,
PatternPtr patterns) PatternPtr patterns)
{ {
char buf[PATH_MAX + 1], tmpBuf[PATH_MAX + 1]; char buf[PATH_MAX + 1];
char *dirpath = NULL; char *dirpath = NULL;
char *name = NULL; char *name = NULL;
struct stat stat_buf;
int dirlen; int dirlen;
const char **subdirs = NULL; const char **subdirs = NULL;
const char **s; const char **s;
#ifndef __EMX__ dirpath = (char *)dirname;
dirpath = (char *)dir;
#else
dirpath = xalloc(strlen(dir) + 10);
strcpy(dirpath, (char *)__XOS2RedirRoot(dir));
#endif
if (strlen(dirpath) > PATH_MAX) if (strlen(dirpath) > PATH_MAX)
return NULL; return NULL;
@ -418,38 +460,15 @@ FindModule(const char *module, const char *dir, const char **subdirlist,
continue; continue;
strcpy(buf, dirpath); strcpy(buf, dirpath);
strcat(buf, *s); strcat(buf, *s);
if ((stat(buf, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) { if ((name = FindModuleInSubdir(buf, module)))
if (buf[dirlen - 1] != '/') {
buf[dirlen++] = '/';
}
snprintf(tmpBuf, PATH_MAX, "%slib%s.so", buf, module);
if (stat(tmpBuf, &stat_buf) == 0) {
name = tmpBuf;
break; break;
} }
snprintf(tmpBuf, PATH_MAX, "%s%s_drv.so", buf, module);
if (stat(tmpBuf, &stat_buf) == 0) {
name = tmpBuf;
break;
}
snprintf(tmpBuf, PATH_MAX, "%s%s.so", buf, module);
if (stat(tmpBuf, &stat_buf) == 0) {
name = tmpBuf;
break;
}
}
}
FreeSubdirs(subdirs); FreeSubdirs(subdirs);
if (dirpath != dir) if (dirpath != dirname)
xfree(dirpath); xfree(dirpath);
if (name) { return name;
return xstrdup(name);
}
return NULL;
} }
_X_EXPORT char ** _X_EXPORT char **