summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2006-07-21 19:57:28 -0400
committerDaniel Stone <daniels@endtroducing.fooishbar.org>2006-07-21 19:58:15 -0400
commit6cf844ab69926b6d23619a12c97734af3881ba67 (patch)
tree4a9e68a9a3da606a2df58745313d534739f37f2b /hw
parent63dfaa1d5ba556e09314ec914936e5471aab94b0 (diff)
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.
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/loader/loadmod.c93
1 files changed, 56 insertions, 37 deletions
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index fd84a924c..53dcffef3 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -389,23 +389,65 @@ FreeSubdirs(const char **subdirs)
}
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)
{
- char buf[PATH_MAX + 1], tmpBuf[PATH_MAX + 1];
+ char buf[PATH_MAX + 1];
char *dirpath = NULL;
char *name = NULL;
- struct stat stat_buf;
int dirlen;
const char **subdirs = NULL;
const char **s;
-#ifndef __EMX__
- dirpath = (char *)dir;
-#else
- dirpath = xalloc(strlen(dir) + 10);
- strcpy(dirpath, (char *)__XOS2RedirRoot(dir));
-#endif
+ dirpath = (char *)dirname;
if (strlen(dirpath) > PATH_MAX)
return NULL;
@@ -418,38 +460,15 @@ FindModule(const char *module, const char *dir, const char **subdirlist,
continue;
strcpy(buf, dirpath);
strcat(buf, *s);
- if ((stat(buf, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
- if (buf[dirlen - 1] != '/') {
- buf[dirlen++] = '/';
- }
-
- snprintf(tmpBuf, PATH_MAX, "%slib%s.so", buf, module);
- if (stat(tmpBuf, &stat_buf) == 0) {
- name = tmpBuf;
- 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;
- }
- }
+ if ((name = FindModuleInSubdir(buf, module)))
+ break;
}
+
FreeSubdirs(subdirs);
- if (dirpath != dir)
+ if (dirpath != dirname)
xfree(dirpath);
- if (name) {
- return xstrdup(name);
- }
- return NULL;
+ return name;
}
_X_EXPORT char **