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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
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;
}
示例#5
0
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;
}
示例#6
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;
}