void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list, char **devname) { DIR *dir; struct dirent *dp; struct stat st; if ((dir = opendir(dirname)) == NULL) return; while ((dp = readdir(dir)) != NULL) { #ifdef _DIRENT_HAVE_D_TYPE if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_BLK && dp->d_type != DT_LNK && dp->d_type != DT_DIR) continue; #endif if (dp->d_name[0] == '.' && ((dp->d_name[1] == 0) || ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) continue; if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 0)) continue; if (S_ISBLK(st.st_mode) && st.st_rdev == devno) { *devname = blkid_strconcat(dirname, "/", dp->d_name); DBG(DEBUG_DEVNO, printf("found 0x%llx at %s\n", (long long)devno, *devname)); break; } if (!list || !S_ISDIR(st.st_mode)) continue; /* add subdirectory (but not symlink) to the list */ #ifdef _DIRENT_HAVE_D_TYPE if (dp->d_type == DT_LNK) continue; if (dp->d_type == DT_UNKNOWN) #endif { if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 1) || !S_ISDIR(st.st_mode)) continue; /* symlink or lstat() failed */ } if (*dp->d_name == '.' || ( #ifdef _DIRENT_HAVE_D_TYPE dp->d_type == DT_DIR && #endif strcmp(dp->d_name, "shm") == 0)) /* ignore /dev/.{udev,mount,mdadm} and /dev/shm */ continue; add_to_dirlist(dirname, dp->d_name, list); } closedir(dir); return; }
int sysfs_stat(struct sysfs_cxt *cxt, const char *attr, struct stat *st) { int rc = fstat_at(cxt->dir_fd, cxt->dir_path, attr, st, 0); if (rc != 0 && errno == ENOENT && strncmp(attr, "queue/", 6) == 0 && cxt->parent) { /* Exception for "queue/<attr>". These attributes are available * for parental devices only */ return fstat_at(cxt->parent->dir_fd, cxt->parent->dir_path, attr, st, 0); } return rc; }
static int mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname) { int n = 0, i; DIR *dir = NULL; struct dirent **namelist = NULL; /* TODO: it would be nice to have a scandir() implementation that * is able to use already opened directory */ n = scandir(dirname, &namelist, NULL, versionsort); if (n <= 0) return 0; /* let use "at" functions rather than play crazy games with paths... */ dir = opendir(dirname); if (!dir) return -errno; for (i = 0; i < n; i++) { struct dirent *d = namelist[i]; struct stat st; size_t namesz; FILE *f; #ifdef _DIRENT_HAVE_D_TYPE if (d->d_type != DT_UNKNOWN && d->d_type != DT_REG && d->d_type != DT_LNK) continue; #endif if (*d->d_name == '.') continue; #define MNT_MNTTABDIR_EXTSIZ (sizeof(MNT_MNTTABDIR_EXT) - 1) namesz = strlen(d->d_name); if (!namesz || namesz < MNT_MNTTABDIR_EXTSIZ + 1 || strcmp(d->d_name + (namesz - MNT_MNTTABDIR_EXTSIZ), MNT_MNTTABDIR_EXT)) continue; if (fstat_at(dirfd(dir), _PATH_MNTTAB_DIR, d->d_name, &st, 0) || !S_ISREG(st.st_mode)) continue; f = fopen_at(dirfd(dir), _PATH_MNTTAB_DIR, d->d_name, O_RDONLY, "r"); if (f) { mnt_table_parse_stream(tb, f, d->d_name); fclose(f); } } for (i = 0; i < n; i++) free(namelist[i]); free(namelist); if (dir) closedir(dir); return 0; }
static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname) { int n = 0, i, r = 0; DIR *dir = NULL; struct dirent **namelist = NULL; n = scandir(dirname, &namelist, mnt_table_parse_dir_filter, versionsort); if (n <= 0) return 0; /* let use "at" functions rather than play crazy games with paths... */ dir = opendir(dirname); if (!dir) { r = -errno; goto out; } for (i = 0; i < n; i++) { struct dirent *d = namelist[i]; struct stat st; FILE *f; if (fstat_at(dirfd(dir), _PATH_MNTTAB_DIR, d->d_name, &st, 0) || !S_ISREG(st.st_mode)) continue; f = fopen_at(dirfd(dir), _PATH_MNTTAB_DIR, d->d_name, O_RDONLY, "r"); if (f) { mnt_table_parse_stream(tb, f, d->d_name); fclose(f); } } out: for (i = 0; i < n; i++) free(namelist[i]); free(namelist); if (dir) closedir(dir); return r; }
static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname) { int n = 0, i; int dd; struct dirent **namelist = NULL; dd = open(dirname, O_RDONLY|O_CLOEXEC|O_DIRECTORY); if (dd < 0) return -errno; n = scandirat(dd, ".", &namelist, mnt_table_parse_dir_filter, versionsort); if (n <= 0) { close(dd); return 0; } for (i = 0; i < n; i++) { struct dirent *d = namelist[i]; struct stat st; FILE *f; if (fstat_at(dd, ".", d->d_name, &st, 0) || !S_ISREG(st.st_mode)) continue; f = fopen_at(dd, ".", d->d_name, O_RDONLY, "r"); if (f) { mnt_table_parse_stream(tb, f, d->d_name); fclose(f); } } for (i = 0; i < n; i++) free(namelist[i]); free(namelist); close(dd); return 0; }
int proc_next_pid(struct proc_processes *ps, pid_t *pid) { struct dirent *d; if (!ps || !pid) return -EINVAL; *pid = 0; errno = 0; do { char buf[BUFSIZ], *p; d = readdir(ps->dir); if (!d) return errno ? -1 : 1; /* error or end-of-dir */ if (!isdigit((unsigned char) *d->d_name)) continue; /* filter out by UID */ if (ps->has_fltr_uid) { struct stat st; if (fstat_at(dirfd(ps->dir), "/proc", d->d_name, &st, 0)) continue; if (ps->fltr_uid != st.st_uid) continue; } /* filter out by NAME */ if (ps->has_fltr_name) { char procname[256]; FILE *f; snprintf(buf, sizeof(buf), "%s/stat", d->d_name); f = fopen_at(dirfd(ps->dir), "/proc", buf, O_CLOEXEC|O_RDONLY, "r"); if (!f) continue; p = fgets(buf, sizeof(buf), f); fclose(f); if (sscanf(buf, "%*d (%255[^)])", procname) != 1) continue; /* ok, we got the process name. */ if (strcmp(procname, ps->fltr_name) != 0) continue; } p = NULL; errno = 0; *pid = (pid_t) strtol(d->d_name, &p, 10); if (errno || d->d_name == p || (p && *p)) return errno ? -errno : -1; return 0; } while (1); return 0; }