readdir() is not thread-safe. Use readdir_r instead.
struct kmod_list *list = NULL;
DIR *d;
int dfd;
struct kmod_list *list = NULL;
DIR *d;
int dfd;
if (mod == NULL)
return NULL;
if (mod == NULL)
return NULL;
- while ((de = readdir(d)) != NULL) {
+
+ for (;;) {
+ struct dirent de, *entp;
struct kmod_module_section *section;
struct kmod_module_section *section;
- struct kmod_list *node;
unsigned long address;
size_t namesz;
int fd, err;
unsigned long address;
size_t namesz;
int fd, err;
- if (de->d_name[0] == '.') {
- if (de->d_name[1] == '\0' ||
- (de->d_name[1] == '.' && de->d_name[2] == '\0'))
+ err = readdir_r(d, &de, &entp);
+ if (err != 0) {
+ ERR(mod->ctx, "could not iterate for module '%s': %s\n",
+ mod->name, strerror(-err));
+ goto fail;
+ }
+
+ if (de.d_name[0] == '.') {
+ if (de.d_name[1] == '\0' ||
+ (de.d_name[1] == '.' && de.d_name[2] == '\0'))
- fd = openat(dfd, de->d_name, O_RDONLY);
+ fd = openat(dfd, de.d_name, O_RDONLY);
- ERR(mod->ctx, "could not open '%s/%s': %s\n",
- dname, de->d_name, strerror(errno));
- continue;
+ ERR(mod->ctx, "could not open '%s/%s': %m\n",
+ dname, de.d_name);
+ goto fail;
}
err = read_str_ulong(fd, &address, 16);
}
err = read_str_ulong(fd, &address, 16);
- ERR(mod->ctx, "could not read long from '%s/%s': %s\n",
- dname, de->d_name, strerror(-err));
- close(fd);
- continue;
+ ERR(mod->ctx, "could not read long from '%s/%s': %m\n",
+ dname, de.d_name);
+ goto fail;
+ }
+
+ namesz = strlen(de.d_name) + 1;
+ section = malloc(sizeof(*section) + namesz);
+
+ if (section == NULL) {
+ ERR(mod->ctx, "out of memory\n");
+ goto fail;
- namesz = strlen(de->d_name) + 1;
- section = malloc(sizeof(struct kmod_module_section) + namesz);
section->address = address;
section->address = address;
- memcpy(section->name, de->d_name, namesz);
+ memcpy(section->name, de.d_name, namesz);
- node = kmod_list_append(list, section);
- if (node)
- list = node;
- else {
+ l = kmod_list_append(list, section);
+ if (l != NULL) {
+ list = l;
+ } else {
ERR(mod->ctx, "out of memory\n");
free(section);
ERR(mod->ctx, "out of memory\n");
free(section);
}
closedir(d);
return list;
}
closedir(d);
return list;
+
+fail:
+ closedir(d);
+ kmod_module_unref_list(list);
+ return NULL;
}
KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)
}
KMOD_EXPORT const char *kmod_module_section_get_name(const struct kmod_list *entry)