#define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include #include #define SECTOR_SHIFT 9 int main(int argc, char **argv) { int f, r; unsigned long size; unsigned long bufsize; unsigned int pagesize; off_t offset; char *endptr; char *buffer; int mode = 'z'; if (argc > 1 && argv[1][0] == '-') { mode = argv[1][1]; argv++; argc--; } if (argc < 3) return 1; size = strtol(argv[2], &endptr, 10); if (*endptr || !size || size > 4096) return 1; size <<= SECTOR_SHIFT; bufsize = (size + pagesize - 1) & ~(pagesize - 1); if (argc >= 4) { offset = (off_t)strtoll(argv[3], &endptr, 10); if (*endptr) return 1; offset <<= SECTOR_SHIFT; } else offset = 0; f = open(argv[1], ((mode == 'w' || mode == 'z') ? O_WRONLY : O_RDONLY) | O_DIRECT | O_SYNC); if (f < 0) { perror("fopen"); return 1; } if (offset) { if (lseek(f, offset, SEEK_SET) != offset) { perror("lseek"); return 1; } } buffer = mmap(NULL, bufsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); if (!buffer) { perror("mmap"); close(f); return 1; } if (mode == 'z') memset(buffer, 0, size); else if (mode == 'w') read(0, buffer, size); if (mode == 'z' || mode == 'w') r = write(f, buffer, size); else if (mode == 'v' || mode == 'r') r = read(f, buffer, size); if (mode == 'v') { char *start = buffer; char *end = buffer + size; while(start != end) if (*start++) { fprintf(stderr, "Verify failed at %08x\n", (start - buffer) - 1); break; } } else if (mode == 'r') write(1, buffer, size); munmap(buffer, bufsize); close(f); if (r < 0) { perror("write"); return 1; } fprintf(stderr, "Result: %d\n", r); return 0; }