vm: fix region reporting bug
[minix.git] / test / fbdtest / rwblocks.c
blob74aba62dee87235b0b87b58a3c91bb3156675c5a
1 /* Simple block pattern reader/writer for testing FBD */
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <fcntl.h>
9 #define BLOCK_SIZE 4096 /* set to match root FS to prevent partial I/O */
11 static int flush_buf(int fd, char *buf, size_t size, size_t write_size)
13 ssize_t r;
15 while (write_size <= size) {
16 if ((r = write(fd, buf, write_size)) != write_size) {
17 if (r < 0)
18 perror("write");
19 else
20 fprintf(stderr, "short write (%d < %d)\n",
21 r, write_size);
23 return EXIT_FAILURE;
26 sync();
28 buf += write_size;
29 size -= write_size;
32 return EXIT_SUCCESS;
35 static int write_pattern(int fd, char *pattern, int write_size)
37 char *buf, *ptr;
38 size_t size;
39 int r, count, nblocks;
41 /* Only write sizes that are a multiple or a
42 * divisor of the block size, are supported.
44 nblocks = write_size / BLOCK_SIZE;
45 if (!nblocks) nblocks = 1;
46 size = nblocks * BLOCK_SIZE;
48 if ((buf = malloc(size)) == NULL) {
49 perror("malloc");
51 return EXIT_FAILURE;
54 count = 0;
56 do {
57 ptr = &buf[count * BLOCK_SIZE];
59 switch (*pattern) {
60 case 'A':
61 case 'B':
62 case 'C':
63 case 'D':
64 case 'U':
65 memset(ptr, *pattern, BLOCK_SIZE);
66 break;
68 case '0':
69 memset(ptr, 0, BLOCK_SIZE);
70 break;
72 case '\0':
73 memset(ptr, 0, BLOCK_SIZE);
74 ptr[0] = 'E';
75 ptr[1] = 'O';
76 ptr[2] = 'F';
79 if (++count == nblocks) {
80 if ((r = flush_buf(fd, buf, size, write_size)) !=
81 EXIT_SUCCESS) {
82 free(buf);
84 return r;
87 count = 0;
89 } while (*pattern++);
91 if (count > 0)
92 r = flush_buf(fd, buf, count * BLOCK_SIZE, write_size);
93 else
94 r = EXIT_SUCCESS;
96 free(buf);
98 return r;
101 static int read_pattern(int fd)
103 char buf[BLOCK_SIZE];
104 unsigned int i, val;
105 ssize_t r;
107 for (;;) {
108 memset(buf, '?', sizeof(buf));
110 if ((r = read(fd, buf, sizeof(buf))) != sizeof(buf)) {
111 putchar('#');
113 if (!r) break; /* stop at hard EOF */
115 lseek(fd, sizeof(buf), SEEK_CUR);
117 continue;
120 if (buf[0] == 'E' && buf[1] == 'O' && buf[2] == 'F') {
121 for (i = 3; i < sizeof(buf); i++)
122 if (buf[i] != 0) break;
124 if (i == sizeof(buf)) break;
127 for (i = 1; i < sizeof(buf); i++)
128 if (buf[i] != buf[0]) break;
130 if (i == sizeof(buf)) {
131 switch (buf[0]) {
132 case 'A':
133 case 'B':
134 case 'C':
135 case 'D':
136 case 'U':
137 case '?':
138 printf("%c", buf[0]);
139 break;
141 case '\0':
142 printf("0");
143 break;
145 default:
146 printf("X");
149 continue;
152 for (i = val = 0; i < sizeof(buf); i++)
153 val += buf[i];
155 printf("%c", 'a' + val % 26);
158 printf("\n");
160 return EXIT_SUCCESS;
163 int main(int argc, char **argv)
165 int fd, r;
167 if (argc < 2) {
168 fprintf(stderr, "usage: %s <device> [pattern [writesz]]\n",
169 argv[0]);
171 return EXIT_FAILURE;
174 fd = open(argv[1], (argc > 2) ? O_WRONLY : O_RDONLY);
175 if (fd < 0) {
176 perror("open");
178 return EXIT_FAILURE;
181 if (argc > 2)
182 r = write_pattern(fd, argv[2],
183 argv[3] ? atoi(argv[3]) : BLOCK_SIZE);
184 else
185 r = read_pattern(fd);
187 close(fd);
189 return r;