📄 integck.c
字号:
buf[written] = rand(); /* Write a block of data */ if (remains > BUFFER_SIZE) block = BUFFER_SIZE; else block = remains; written = write(fd, buf, block); CHECK(written == block); remains -= written; }}static void save_file(int fd, struct file_info *file){ int w_fd; struct write_info *w; char buf[BUFFER_SIZE]; char name[256]; /* Open file to save contents to */ strcpy(name, "/tmp/"); strcat(name, file->name); strcat(name, ".integ.sav.read"); fprintf(stderr, "Saving %s\n", name); w_fd = open(name, O_CREAT | O_WRONLY, 0777); CHECK(w_fd != -1); /* Start at the beginning */ CHECK(lseek(fd, 0, SEEK_SET) != (off_t) -1); for (;;) { ssize_t r = read(fd, buf, BUFFER_SIZE); CHECK(r != -1); if (!r) break; CHECK(write(w_fd, buf, r) == r); } CHECK(close(w_fd) != -1); /* Open file to save contents to */ strcpy(name, "/tmp/"); strcat(name, file->name); strcat(name, ".integ.sav.written"); fprintf(stderr, "Saving %s\n", name); w_fd = open(name, O_CREAT | O_WRONLY, 0777); CHECK(w_fd != -1); for (w = file->writes; w; w = w->next) file_rewrite_data(w_fd, w, buf); CHECK(close(w_fd) != -1);}static void file_check_hole( struct file_info *file, int fd, off_t offset, size_t size){ size_t remains, block, i; char buf[BUFFER_SIZE]; CHECK(lseek(fd, offset, SEEK_SET) != (off_t) -1); remains = size; while (remains) { if (remains > BUFFER_SIZE) block = BUFFER_SIZE; else block = remains; CHECK(read(fd, buf, block) == block); for (i = 0; i < block; ++i) { if (buf[i] != 0) { fprintf(stderr, "file_check_hole failed at %u " "checking hole at %u size %u\n", (unsigned) (size - remains + i), (unsigned) offset, (unsigned) size); file_info_display(file); save_file(fd, file); } CHECK(buf[i] == 0); } remains -= block; }}static void file_check_data( struct file_info *file, int fd, struct write_info *w){ size_t remains, block, i; off_t r; char buf[BUFFER_SIZE]; srand(w->random_seed); for (r = 0; r < w->random_offset; ++r) rand(); CHECK(lseek(fd, w->offset, SEEK_SET) != (off_t) -1); remains = w->size; while (remains) { if (remains > BUFFER_SIZE) block = BUFFER_SIZE; else block = remains; CHECK(read(fd, buf, block) == block); for (i = 0; i < block; ++i) { char c = (char) rand(); if (buf[i] != c) { fprintf(stderr, "file_check_data failed at %u " "checking data at %u size %u\n", (unsigned) (w->size - remains + i), (unsigned) w->offset, (unsigned) w->size); file_info_display(file); save_file(fd, file); } CHECK(buf[i] == c); } remains -= block; }}static void file_check(struct file_info *file, int fd){ int open_and_close = 0, link_count = 0; char *path = NULL; off_t pos; struct write_info *w; struct dir_entry_info *entry; struct stat st; /* Do not check files that have errored */ if (!check_nospc_files && file->no_space_error) return; /* Do not check the same file twice */ if (file->check_run_no == check_run_no) return; file->check_run_no = check_run_no; if (fd == -1) open_and_close = 1; if (open_and_close) { /* Open file */ path = dir_path(file->links->parent, file->links->name); fd = open(path, O_RDONLY); CHECK(fd != -1); } /* Check length */ pos = lseek(fd, 0, SEEK_END); if (pos != file->length) { fprintf(stderr, "file_check failed checking length " "expected %u actual %u\n", (unsigned) file->length, (unsigned) pos); file_info_display(file); save_file(fd, file); } CHECK(pos == file->length); /* Check each write */ pos = 0; for (w = file->writes; w; w = w->next) { if (w->offset > pos) file_check_hole(file, fd, pos, w->offset - pos); file_check_data(file, fd, w); pos = w->offset + w->size; } if (file->length > pos) file_check_hole(file, fd, pos, file->length - pos); CHECK(fstat(fd, &st) != -1); CHECK(file->link_count == st.st_nlink); if (open_and_close) { CHECK(close(fd) != -1); free(path); } entry = file->links; while (entry) { link_count += 1; entry = entry->next_link; } CHECK(link_count == file->link_count);}static char *symlink_path(const char *path, const char *target_pathname){ char *p; size_t len, totlen, tarlen; if (target_pathname[0] == '/') return copy_string(target_pathname); p = strrchr(path, '/'); len = p - path; len += 1; tarlen = strlen(target_pathname); totlen = len + tarlen + 1; p = malloc(totlen); CHECK(p != NULL); strncpy(p, path, len); p[len] = '\0'; strcat(p, target_pathname); return p;}void symlink_check(const struct symlink_info *symlink){ char *path, buf[8192], *target; struct stat st1, st2; ssize_t len; int ret1, ret2; path = dir_path(symlink->entry->parent, symlink->entry->name); CHECK(lstat(path, &st1) != -1); CHECK(S_ISLNK(st1.st_mode)); CHECK(st1.st_nlink == 1); len = readlink(path, buf, 8192); CHECK(len > 0 && len < 8192); buf[len] = '\0'; CHECK(strlen(symlink->target_pathname) == len); CHECK(strncmp(symlink->target_pathname, buf, len) == 0); /* Check symlink points where it should */ ret1 = stat(path, &st1); target = symlink_path(path, symlink->target_pathname); ret2 = stat(target, &st2); CHECK(ret1 == ret2); if (ret1 != -1) { CHECK(st1.st_dev == st2.st_dev); CHECK(st1.st_ino == st2.st_ino); } free(target); free(path);}static int search_comp(const void *pa, const void *pb){ const struct dirent *a = (const struct dirent *) pa; const struct dir_entry_info *b = * (const struct dir_entry_info **) pb; return strcmp(a->d_name, b->name);}static void dir_entry_check(struct dir_entry_info **entry_array, size_t number_of_entries, struct dirent *ent){ struct dir_entry_info **found; struct dir_entry_info *entry; size_t sz; sz = sizeof(struct dir_entry_info *); found = bsearch(ent, entry_array, number_of_entries, sz, search_comp); CHECK(found != NULL); entry = *found; CHECK(!entry->checked); entry->checked = 1;}static int sort_comp(const void *pa, const void *pb){ const struct dir_entry_info *a = * (const struct dir_entry_info **) pa; const struct dir_entry_info *b = * (const struct dir_entry_info **) pb; return strcmp(a->name, b->name);}static void dir_check(struct dir_info *dir){ struct dir_entry_info **entry_array, **p; size_t sz, n; struct dir_entry_info *entry; DIR *d; struct dirent *ent; unsigned checked = 0; char *path; int link_count = 2; /* Parent and dot */ struct stat st; /* Create an array of entries */ sz = sizeof(struct dir_entry_info *); n = dir->number_of_entries; entry_array = (struct dir_entry_info **) malloc(sz * n); CHECK(entry_array != NULL); entry = dir->first; p = entry_array; while (entry) { *p++ = entry; entry->checked = 0; entry = entry->next; } /* Sort it by name */ qsort(entry_array, n, sz, sort_comp); /* Go through directory on file system checking entries match */ path = dir_path(dir->parent, dir->name); d = opendir(path); CHECK(d != NULL); for (;;) { errno = 0; ent = readdir(d); if (ent) { if (strcmp(".",ent->d_name) != 0 && strcmp("..",ent->d_name) != 0) { dir_entry_check(entry_array, n, ent); checked += 1; } } else { CHECK(errno == 0); break; } } CHECK(closedir(d) != -1); CHECK(checked == dir->number_of_entries); /* Now check each entry */ entry = dir->first; while (entry) { if (entry->type == 'd') { dir_check(entry->entry.dir); link_count += 1; /* <subdir>/.. */ } else if (entry->type == 'f') file_check(entry->entry.file, -1); else if (entry->type == 's') symlink_check(entry->entry.symlink); else CHECK(0); entry = entry->next; } CHECK(stat(path, &st) != -1); CHECK(link_count == st.st_nlink); free(entry_array); free(path);}static void check_deleted_files(void){ struct open_file_info *ofi; for (ofi = open_files; ofi; ofi = ofi->next) if (ofi->fdi->file->deleted) file_check(ofi->fdi->file, ofi->fdi->fd);}static void close_open_files(void){ struct open_file_info *ofi; for (ofi = open_files; ofi; ofi = open_files) file_close(ofi->fdi);}static char *make_name(struct dir_info *dir){ static char name[256]; struct dir_entry_info *entry; int found; do { found = 0; if (tests_random_no(5) == 1) { int i, n = tests_random_no(tests_max_fname_len) + 1; CHECK(n > 0 && n < 256); for (i = 0; i < n; i++) name[i] = 'a' + tests_random_no(26); name[i] = '\0'; } else sprintf(name, "%u", (unsigned) tests_random_no(1000000)); for (entry = dir->first; entry; entry = entry->next) { if (strcmp(entry->name, name) == 0) { found = 1; break; } } } while (found); return name;}static struct file_info *pick_file(void){ struct dir_info *dir = top_dir; for (;;) { struct dir_entry_info *entry; size_t r; r = tests_random_no(dir->number_of_entries); entry = dir->first; while (entry && r) { entry = entry->next; --r; } for (;;) { if (!entry) return NULL; if (entry->type == 'f') return entry->entry.file; if (entry->type == 'd') if (entry->entry.dir->number_of_entries != 0) break; entry = entry->next; } dir = entry->entry.dir; }}static struct dir_info *pick_dir(void){ struct dir_info *dir = top_dir; if (tests_random_no(40) >= 30) return dir; for (;;) { struct dir_entry_info *entry; size_t r; r = tests_random_no(dir->number_of_entries); entry = dir->first; while (entry && r) { entry = entry->next; --r; } for (;;) { if (!entry) break; if (entry->type == 'd') break; entry = entry->next; } if (!entry) { entry = dir->first; for (;;) { if (!entry) break; if (entry->type == 'd') break; entry = entry->next; } } if (!entry) return dir; dir = entry->entry.dir; if (tests_random_no(40) >= 30) return dir; }}static char *pick_rename_name(struct dir_info **parent, struct dir_entry_info **rename_entry, int isdir){ struct dir_info *dir = pick_dir(); struct dir_entry_info *entry; size_t r; *parent = dir; *rename_entry = NULL; if (grow || tests_random_no(20) < 10) return copy_string(make_name(dir)); r = tests_random_no(dir->number_of_entries); entry = dir->first; while (entry && r) { entry = entry->next; --r; } if (!entry) entry = dir->first; if (!entry || (entry->type == 'd' && entry->entry.dir->number_of_entries != 0)) return copy_string(make_name(dir)); if ((isdir && entry->type != 'd') || (!isdir && entry->type == 'd')) return copy_string(make_name(dir)); *rename_entry = entry; return copy_string(entry->name);}static void rename_entry(struct dir_entry_info *entry){ struct dir_entry_info *rename_entry = NULL; struct dir_info *parent; char *path, *to, *name; int ret, isdir, retry; if (!entry->parent) return; for (retry = 0; retry < 3; retry++) { path = dir_path(entry->parent, entry->name); isdir = entry->type == 'd' ? 1 : 0; name = pick_rename_name(&parent, &rename_entry, isdir); to = dir_path(parent, name); /* * Check we are not trying to move a directory to a subdirectory * of itself. */ if (isdir) { struct dir_info *p; for (p = parent; p; p = p->parent) if (p == entry->entry.dir) break; if (p == entry->entry.dir) { free(path); free(name); free(to); path = NULL; continue; } } break; } if (!path) return; ret = rename(path, to); if (ret == -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -