Linux driver 遍历指定文件夹查找文件

linux 应用层可以使用opendir, readdir, closedir接口进行文件夹遍历.

API接口位于 linux/fs/readdir.c


linux driver层, 则可以使用file_operation中的readdir接口进行读取.


typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);

struct file_operations {

	int (*readdir) (struct file *, void *, filldir_t);
};


示例如下:

以下是查找指定目录下的.txt或.ini文件

static int tmp_filldir(void *buf, const char *name, int namelen,
	loff_t offset, u64 ino, unsigned d_type)
{
	unsigned long d_ino;

	d_ino = ino;
	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
		return -EOVERFLOW;
	}
	if (namelen > 0) {
		memcpy(buf, name, namelen);
		return 0;
	}
	return -ENOENT;
}

static int linux_get_file_path(const char *dirpath, char *full_path)
{
	struct file *pfile;
	mm_segment_t old_fs;
	char read_buf[100] = {0};
	int ret;
	int err;

	pfile = filp_open(dirpath, O_RDONLY, 0);
	if (IS_ERR(pfile)) {
		pr_err("Open %s failed!\n", dirpath);
		return -EINVAL; 
	}
	old_fs = get_fs();
	set_fs(KERNEL_DS);

	err = -ENOENT;
	if (pfile->f_op->readdir) {
		while (true) {
			ret = pfile->f_op->readdir(pfile, read_buf, tmp_filldir);
			if (ret || (read_buf[0] == '\0')) {
				break;
			}
			if (strstr(read_buf, ".txt") || strstr(read_buf, ".TXT") ||
				strstr(read_buf, ".ini") || strstr(read_buf, ".ini")) {
					// for too long filename
					*(extstr+4) = '\0';
					snprintf(full_path, PATH_MAX, "%s/%s", dirpath, read_buf);
					pr_err("find file: %s\n", read_buf);
					err = 0;
					break;
			}
			memset(read_buf, 0, 100);
		}
	}

	filp_close(pfile, NULL);
	set_fs(old_fs);
	return err;
}


调用示例:

#define MY_DIR		"/sdcard/my/dir"

char *filepath = NULL;

filepath = kzalloc(PATH_MAX, GFP_KERNEL);
if (!filepath) {
	pr_err("allocate mem for porch failed!\n");
	return;
}
ret = linux_get_file_path(MY_DIR, filepath);
if (ret) {
	pr_err("file not found, use default porch.txt!\n");
	snprintf(filepath, PATH_MAX, "%s/%s", MY_DIR, "porch.txt");
}



猜你喜欢

转载自blog.csdn.net/meta_cpp/article/details/78665887