1 /* 2 * Copyright 2010, Axel Dörfler, axeld@pinc-software.de. 3 * This file may be used under the terms of the MIT License. 4 */ 5 6 7 #include <fcntl.h> 8 #include <stdio.h> 9 #include <string.h> 10 #include <unistd.h> 11 12 #include <algorithm> 13 14 15 void 16 test_for_content(int fd, off_t start, const char* contents, size_t length) 17 { 18 char buffer[4096]; 19 while (length > 0) { 20 size_t toRead = std::min(length, sizeof(buffer)); 21 22 if (pread(fd, buffer, toRead, start) != (ssize_t)toRead) { 23 perror("reading failed"); 24 exit(1); 25 } 26 27 if (memcmp(contents, buffer, toRead)) { 28 fprintf(stderr, "Contents at %lld differ!\n", start); 29 exit(1); 30 } 31 32 contents += toRead; 33 start += toRead; 34 length -= toRead; 35 } 36 } 37 38 39 void 40 test_for_zero(int fd, off_t start, off_t end) 41 { 42 while (start < end) { 43 char buffer[4096]; 44 size_t length = std::min((size_t)(end - start), sizeof(buffer)); 45 46 if (pread(fd, buffer, length, start) != (ssize_t)length) { 47 perror("reading failed"); 48 exit(1); 49 } 50 51 for (size_t i = 0; i < length; i++) { 52 if (buffer[i] != 0) { 53 fprintf(stderr, "Buffer at %lld is not empty (%#x)!\n", 54 start + i, buffer[i]); 55 exit(1); 56 } 57 } 58 59 start += length; 60 } 61 } 62 63 64 int 65 main(int argc, char** argv) 66 { 67 const char* name = "/tmp/seek_and_write"; 68 bool prefill = true; 69 70 for (int i = 1; i < argc; i++) { 71 if (argv[i][0] == '-') { 72 if (argv[i][1] == 'n') 73 prefill = false; 74 else { 75 fprintf(stderr, "Unknown option\n"); 76 return 1; 77 } 78 79 continue; 80 } 81 82 name = argv[i]; 83 } 84 85 int fd = open(name, O_RDWR | O_TRUNC | O_CREAT, 0644); 86 if (fd < 0) { 87 perror("failed to open file"); 88 return 1; 89 } 90 91 char buffer[256]; 92 for (size_t i = 0; i < 256; i++) 93 buffer[i] = i; 94 95 if (prefill) { 96 // Write test data to file to make sure it's not empty 97 98 for (size_t i = 0; i < 100; i++) { 99 if (write(fd, buffer, sizeof(buffer)) != (ssize_t)sizeof(buffer)) { 100 perror("writing failed"); 101 return 1; 102 } 103 } 104 } 105 106 // Truncate it again in order to remove its contents 107 108 ftruncate(fd, 0); 109 110 // Seek past its end, and write something 111 112 pwrite(fd, "---", 3, 100 * 1024); 113 pwrite(fd, "+++", 3, 200 * 1024); 114 115 // Test contents 116 117 test_for_zero(fd, 0, 100 * 1024); 118 test_for_content(fd, 100 * 1024, "---", 3); 119 test_for_zero(fd, 100 * 1024 + 256, 200 * 1024); 120 test_for_content(fd, 200 * 1024, "+++", 3); 121 122 return 0; 123 } 124