⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tests.c

📁 mtd-utils 是一套更改linux mtd設備的工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	CHECK(fd != -1);	actual_size = tests_fill_file(fd, file_size);	CHECK(close(fd) != -1);	if (file_size != 0 && actual_size == 0)		tests_delete_file(file_name);	else		tests_sync_directory(file_name);	return actual_size;}/* Calculate: free_space * numerator / denominator */uint64_t tests_get_big_file_size(unsigned numerator, unsigned denominator){	if (denominator == 0)		denominator = 1;	if (numerator > denominator)		numerator = denominator;	return numerator * (tests_get_free_space() / denominator);}/* Create file "fragment_n" where n is the file_number, and unlink it */int tests_create_orphan(unsigned file_number){	int fd;	int flags;	mode_t mode;	char file_name[256];	sprintf(file_name, "fragment_%u", file_number);	flags = O_CREAT | O_TRUNC | O_RDWR | tests_maybe_sync_flag();	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;	fd = open(file_name, flags, mode);	if (fd == -1 && (errno == ENOSPC || errno == EMFILE))		return fd; /* File system full or too many open files */	CHECK(fd != -1);	tests_sync_directory(file_name);	CHECK(unlink(file_name) != -1);	return fd;}/* Write size bytes at offset to the file "fragment_n" where n is the   file_number and file_number also determines the random data written   i.e. seed for random numbers */unsigned tests_write_fragment_file(unsigned file_number,				int fd,				off_t offset,				unsigned size){	int i, d;	uint64_t u;	ssize_t written;	off_t pos;	char buf[WRITE_BUFFER_SIZE];	if (size > WRITE_BUFFER_SIZE)		size = WRITE_BUFFER_SIZE;	pos = lseek(fd, 0, SEEK_END);	CHECK(pos != (off_t) -1);	if (offset > pos)		offset = pos;	pos = lseek(fd, offset, SEEK_SET);	CHECK(pos != (off_t) -1);	CHECK(pos == offset);	srand(file_number);	while (offset--)		rand();	u = RAND_MAX;	u += 1;	u /= 256;	d = (int) u;	for (i = 0; i < size; ++i)		buf[i] = rand() / d;	written = write(fd, buf, size);	if (written <= 0) {		CHECK(errno == ENOSPC); /* File system full */		errno = 0;		written = 0;	}	tests_maybe_sync(fd);	return (unsigned) written;}/* Write size bytes to the end of file descriptor fd using file_number   to determine the random data written i.e. seed for random numbers */unsigned tests_fill_fragment_file(unsigned file_number, int fd, unsigned size){	off_t offset;	offset = lseek(fd, 0, SEEK_END);	CHECK(offset != (off_t) -1);	return tests_write_fragment_file(file_number, fd, offset, size);}/* Write size bytes to the end of file "fragment_n" where n is the file_number   and file_number also determines the random data written   i.e. seed for random numbers */unsigned tests_append_to_fragment_file(unsigned file_number,					unsigned size,					int create){	int fd;	int flags;	mode_t mode;	unsigned actual_growth;	char file_name[256];	sprintf(file_name, "fragment_%u", file_number);	if (create)		flags = O_CREAT | O_EXCL | O_WRONLY | tests_maybe_sync_flag();	else		flags = O_WRONLY | tests_maybe_sync_flag();	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;	fd = open(file_name, flags, mode);	if (fd == -1 && errno == ENOSPC) {		errno = 0;		return 0; /* File system full */	}	CHECK(fd != -1);	actual_growth = tests_fill_fragment_file(file_number, fd, size);	CHECK(close(fd) != -1);	if (create && !actual_growth)		tests_delete_fragment_file(file_number);	return actual_growth;}/* Write size bytes at offset to the file "fragment_n" where n is the   file_number and file_number also determines the random data written   i.e. seed for random numbers */unsigned tests_overwite_fragment_file(	unsigned file_number,					off_t offset,					unsigned size){	int fd;	unsigned actual_size;	char file_name[256];	sprintf(file_name, "fragment_%u", file_number);	fd = open(file_name, O_RDWR | tests_maybe_sync_flag());	if (fd == -1 && errno == ENOSPC) {		errno = 0;		return 0; /* File system full */	}	CHECK(fd != -1);	actual_size = tests_write_fragment_file(file_number,		fd, offset, size);	CHECK(close(fd) != -1);	return actual_size;}/* Delete file "fragment_n" where n is the file_number */void tests_delete_fragment_file(unsigned file_number){	char file_name[256];	sprintf(file_name, "fragment_%u", file_number);	tests_delete_file(file_name);}/* Check the random data in file "fragment_n" is what is expected */void tests_check_fragment_file_fd(unsigned file_number, int fd){	ssize_t sz, i;	int d;	uint64_t u;	char buf[8192];	CHECK(lseek(fd, 0, SEEK_SET) == 0);	srand(file_number);	u = RAND_MAX;	u += 1;	u /= 256;	d = (int) u;	for (;;) {		sz = read(fd, buf, 8192);		if (sz == 0)			break;		CHECK(sz >= 0);		for (i = 0; i < sz; ++i)			CHECK(buf[i] == (char) (rand() / d));	}}/* Check the random data in file "fragment_n" is what is expected */void tests_check_fragment_file(unsigned file_number){	int fd;	ssize_t sz, i;	int d;	uint64_t u;	char file_name[256];	char buf[8192];	sprintf(file_name, "fragment_%u", file_number);	fd = open(file_name, O_RDONLY);	CHECK(fd != -1);	srand(file_number);	u = RAND_MAX;	u += 1;	u /= 256;	d = (int) u;	for (;;) {		sz = read(fd, buf, 8192);		if (sz == 0)			break;		CHECK(sz >= 0);		for (i = 0; i < sz; ++i)			CHECK(buf[i] == (char) (rand() / d));	}	CHECK(close(fd) != -1);}/* Central point to decide whether to use fsync */void tests_maybe_sync(int fd){	if (tests_ok_to_sync)		CHECK(fsync(fd) != -1);}/* Return O_SYNC if ok to sync otherwise return 0 */int tests_maybe_sync_flag(void){	if (tests_ok_to_sync)		return O_SYNC;	return 0;}/* Return random number from 0 to n - 1 */size_t tests_random_no(size_t n){	uint64_t a, b;	if (!n)		return 0;	if (n - 1 <= RAND_MAX) {		a = rand();		b = RAND_MAX;		b += 1;	} else {		const uint64_t u = 1 + (uint64_t) RAND_MAX;		a = rand();		a *= u;		a += rand();		b = u * u;		CHECK(n <= b);	}	if (RAND_MAX <= UINT32_MAX && n <= UINT32_MAX)		return a * n / b;	else /*if (RAND_MAX <= UINT64_MAX && n <= UINT64_MAX)*/ {		uint64_t x, y;		if (a < n) {			x = a;			y = n;		} else {			x = n;			y = a;		}		return (x * (y / b)) + ((x * (y % b)) / b);	}}/* Make a directory empty */void tests_clear_dir(const char *dir_name){	DIR *dir;	struct dirent *entry;	char buf[4096];	dir = opendir(dir_name);	CHECK(dir != NULL);	CHECK(getcwd(buf, 4096) != NULL);	CHECK(chdir(dir_name) != -1);	for (;;) {		errno = 0;		entry = readdir(dir);		if (entry) {			if (strcmp(".",entry->d_name) != 0 &&					strcmp("..",entry->d_name) != 0) {				if (entry->d_type == DT_DIR) {					tests_clear_dir(entry->d_name);					CHECK(rmdir(entry->d_name) != -1);				} else					CHECK(unlink(entry->d_name) != -1);			}		} else {			CHECK(errno == 0);			break;		}	}	CHECK(chdir(buf) != -1);	CHECK(closedir(dir) != -1);}/* Create an empty sub-directory or small file in the current directory */int64_t tests_create_entry(char *return_name){	int fd;	char name[256];	for (;;) {		sprintf(name, "%u", (unsigned) tests_random_no(10000000));		fd = open(name, O_RDONLY);		if (fd == -1)			break;		close(fd);	}	if (return_name)		strcpy(return_name, name);	if (tests_random_no(2)) {		return tests_create_file(name, tests_random_no(4096));	} else {		if (mkdir(name, 0777) == -1) {			CHECK(errno == ENOSPC);			errno = 0;			return 0;		}		return TESTS_EMPTY_DIR_SIZE;	}}/* Remove a random file of empty sub-directory from the current directory */int64_t tests_remove_entry(void){	DIR *dir;	struct dirent *entry;	unsigned count = 0, pos;	int64_t result = 0;	dir = opendir(".");	CHECK(dir != NULL);	for (;;) {		errno = 0;		entry = readdir(dir);		if (entry) {			if (strcmp(".",entry->d_name) != 0 &&					strcmp("..",entry->d_name) != 0)				++count;		} else {			CHECK(errno == 0);			break;		}	}	pos = tests_random_no(count);	count = 0;	rewinddir(dir);	for (;;) {		errno = 0;		entry = readdir(dir);		if (!entry) {			CHECK(errno == 0);			break;		}		if (strcmp(".",entry->d_name) != 0 &&				strcmp("..",entry->d_name) != 0) {			if (count == pos) {				if (entry->d_type == DT_DIR) {					tests_clear_dir(entry->d_name);					CHECK(rmdir(entry->d_name) != -1);					result = TESTS_EMPTY_DIR_SIZE;				} else {					struct stat st;					CHECK(stat(entry->d_name, &st) != -1);					result = st.st_size;					CHECK(unlink(entry->d_name) != -1);				}			}			++count;		}	}	CHECK(closedir(dir) != -1);	return result;}/* Read mount information from /proc/mounts or /etc/mtab */int tests_get_mount_info(struct mntent *info){	FILE *f;	struct mntent *entry;	int found = 0;	f = fopen("/proc/mounts", "rb");	if (!f)		f = fopen("/etc/mtab", "rb");	CHECK(f != NULL);	while (!found) {		entry = getmntent(f);		if (entry) {			if (strcmp(entry->mnt_dir,				tests_file_system_mount_dir) == 0) {				found = 1;				*info = *entry;			}		} else			break;	}	CHECK(fclose(f) == 0);	return found;}/* Un-mount and re-mount test file system */void tests_remount(void){	struct mntent mount_info;	char *source;	char *target;	char *filesystemtype;	unsigned long mountflags;	void *data;	char cwd[4096];	CHECK(tests_get_mount_info(&mount_info));	if (strcmp(mount_info.mnt_dir,"/") == 0)		return;	CHECK(getcwd(cwd, 4096) != NULL);	CHECK(chdir("/") != -1);	CHECK(umount(tests_file_system_mount_dir) != -1);	source = mount_info.mnt_fsname;	target = tests_file_system_mount_dir;	filesystemtype = tests_file_system_type;	mountflags = 0;	data = mount_info.mnt_opts;	if (data) {		if (strcmp(data, "rw") == 0)			data = NULL;		else if (strncmp(data, "rw,", 3) == 0)			data += 3;	}	CHECK(mount(source, target, filesystemtype, mountflags, data) != -1);	CHECK(chdir(cwd) != -1);}/* Un-mount or re-mount test file system */static void tests_mnt(int mnt){	static struct mntent mount_info;	char *source;	char *target;	char *filesystemtype;	unsigned long mountflags;	void *data;	static char cwd[4096];	if (mnt == 0) {		CHECK(tests_get_mount_info(&mount_info));		if (strcmp(mount_info.mnt_dir,"/") == 0)			return;		CHECK(getcwd(cwd, 4096) != NULL);		CHECK(chdir("/") != -1);		CHECK(umount(tests_file_system_mount_dir) != -1);	} else {		source = mount_info.mnt_fsname;		target = tests_file_system_mount_dir;		filesystemtype = tests_file_system_type;		mountflags = 0;		data = NULL;		CHECK(mount(source, target, filesystemtype, mountflags, data)			!= -1);		CHECK(chdir(cwd) != -1);	}}/* Unmount test file system */void tests_unmount(void){	tests_mnt(0);}/* Mount test file system */void tests_mount(void){	tests_mnt(1);}/* Check whether the test file system is also the root file system */int tests_fs_is_rootfs(void){	struct stat f_info;	struct stat root_f_info;	CHECK(stat(tests_file_system_mount_dir, &f_info) != -1);	CHECK(stat("/", &root_f_info) != -1);	if (f_info.st_dev == root_f_info.st_dev)		return 1;	else		return 0;}/* Try to make a directory empty */void tests_try_to_clear_dir(const char *dir_name){	DIR *dir;	struct dirent *entry;	char buf[4096];	dir = opendir(dir_name);	if (dir == NULL)		return;	if (getcwd(buf, 4096) == NULL || chdir(dir_name) == -1) {		closedir(dir);		return;	}	for (;;) {		errno = 0;		entry = readdir(dir);		if (entry) {			if (strcmp(".",entry->d_name) != 0 &&					strcmp("..",entry->d_name) != 0) {				if (entry->d_type == DT_DIR) {					tests_try_to_clear_dir(entry->d_name);					rmdir(entry->d_name);				} else					unlink(entry->d_name);			}		} else {			CHECK(errno == 0);			break;		}	}	chdir(buf);	closedir(dir);}/* Check whether the test file system is also the current file system */int tests_fs_is_currfs(void){	struct stat f_info;	struct stat curr_f_info;	CHECK(stat(tests_file_system_mount_dir, &f_info) != -1);	CHECK(stat(".", &curr_f_info) != -1);	if (f_info.st_dev == curr_f_info.st_dev)		return 1;	else		return 0;}#define PID_BUF_SIZE 64/* Concatenate a pid to a string in a signal safe way */void tests_cat_pid(char *buf, const char *name, pid_t pid){	char *p;	unsigned x;	const char digits[] = "0123456789";	char pid_buf[PID_BUF_SIZE];	x = (unsigned) pid;	p = pid_buf + PID_BUF_SIZE;	*--p = '\0';	if (x)		while (x) {			*--p = digits[x % 10];			x /= 10;		}	else		*--p = '0';	buf[0] = '\0';	strcat(buf, name);	strcat(buf, p);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -