xref: /minix3/minix/tests/fbdtest/rwblocks.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /* Simple block pattern reader/writer for testing FBD */
2*433d6423SLionel Sambuc 
3*433d6423SLionel Sambuc #include <stdlib.h>
4*433d6423SLionel Sambuc #include <stdio.h>
5*433d6423SLionel Sambuc #include <string.h>
6*433d6423SLionel Sambuc #include <unistd.h>
7*433d6423SLionel Sambuc #include <fcntl.h>
8*433d6423SLionel Sambuc 
9*433d6423SLionel Sambuc #define BLOCK_SIZE 4096	/* set to match root FS to prevent partial I/O */
10*433d6423SLionel Sambuc 
flush_buf(int fd,char * buf,size_t size,size_t write_size)11*433d6423SLionel Sambuc static int flush_buf(int fd, char *buf, size_t size, size_t write_size)
12*433d6423SLionel Sambuc {
13*433d6423SLionel Sambuc 	ssize_t r;
14*433d6423SLionel Sambuc 
15*433d6423SLionel Sambuc 	while (write_size <= size) {
16*433d6423SLionel Sambuc 		if ((r = write(fd, buf, write_size)) != write_size) {
17*433d6423SLionel Sambuc 			if (r < 0)
18*433d6423SLionel Sambuc 				perror("write");
19*433d6423SLionel Sambuc 			else
20*433d6423SLionel Sambuc 				fprintf(stderr, "short write (%d < %d)\n",
21*433d6423SLionel Sambuc 					r, write_size);
22*433d6423SLionel Sambuc 
23*433d6423SLionel Sambuc 			return EXIT_FAILURE;
24*433d6423SLionel Sambuc 		}
25*433d6423SLionel Sambuc 
26*433d6423SLionel Sambuc 		sync();
27*433d6423SLionel Sambuc 
28*433d6423SLionel Sambuc 		buf += write_size;
29*433d6423SLionel Sambuc 		size -= write_size;
30*433d6423SLionel Sambuc 	}
31*433d6423SLionel Sambuc 
32*433d6423SLionel Sambuc 	return EXIT_SUCCESS;
33*433d6423SLionel Sambuc }
34*433d6423SLionel Sambuc 
write_pattern(int fd,char * pattern,int write_size)35*433d6423SLionel Sambuc static int write_pattern(int fd, char *pattern, int write_size)
36*433d6423SLionel Sambuc {
37*433d6423SLionel Sambuc 	char *buf, *ptr;
38*433d6423SLionel Sambuc 	size_t size;
39*433d6423SLionel Sambuc 	int r, count, nblocks;
40*433d6423SLionel Sambuc 
41*433d6423SLionel Sambuc 	/* Only write sizes that are a multiple or a
42*433d6423SLionel Sambuc 	 * divisor of the block size, are supported.
43*433d6423SLionel Sambuc 	 */
44*433d6423SLionel Sambuc 	nblocks = write_size / BLOCK_SIZE;
45*433d6423SLionel Sambuc 	if (!nblocks) nblocks = 1;
46*433d6423SLionel Sambuc 	size = nblocks * BLOCK_SIZE;
47*433d6423SLionel Sambuc 
48*433d6423SLionel Sambuc 	if ((buf = malloc(size)) == NULL) {
49*433d6423SLionel Sambuc 		perror("malloc");
50*433d6423SLionel Sambuc 
51*433d6423SLionel Sambuc 		return EXIT_FAILURE;
52*433d6423SLionel Sambuc 	}
53*433d6423SLionel Sambuc 
54*433d6423SLionel Sambuc 	count = 0;
55*433d6423SLionel Sambuc 
56*433d6423SLionel Sambuc 	do {
57*433d6423SLionel Sambuc 		ptr = &buf[count * BLOCK_SIZE];
58*433d6423SLionel Sambuc 
59*433d6423SLionel Sambuc 		switch (*pattern) {
60*433d6423SLionel Sambuc 		case 'A':
61*433d6423SLionel Sambuc 		case 'B':
62*433d6423SLionel Sambuc 		case 'C':
63*433d6423SLionel Sambuc 		case 'D':
64*433d6423SLionel Sambuc 		case 'U':
65*433d6423SLionel Sambuc 			memset(ptr, *pattern, BLOCK_SIZE);
66*433d6423SLionel Sambuc 			break;
67*433d6423SLionel Sambuc 
68*433d6423SLionel Sambuc 		case '0':
69*433d6423SLionel Sambuc 			memset(ptr, 0, BLOCK_SIZE);
70*433d6423SLionel Sambuc 			break;
71*433d6423SLionel Sambuc 
72*433d6423SLionel Sambuc 		case '\0':
73*433d6423SLionel Sambuc 			memset(ptr, 0, BLOCK_SIZE);
74*433d6423SLionel Sambuc 			ptr[0] = 'E';
75*433d6423SLionel Sambuc 			ptr[1] = 'O';
76*433d6423SLionel Sambuc 			ptr[2] = 'F';
77*433d6423SLionel Sambuc 		}
78*433d6423SLionel Sambuc 
79*433d6423SLionel Sambuc 		if (++count == nblocks) {
80*433d6423SLionel Sambuc 			if ((r = flush_buf(fd, buf, size, write_size)) !=
81*433d6423SLionel Sambuc 					EXIT_SUCCESS) {
82*433d6423SLionel Sambuc 				free(buf);
83*433d6423SLionel Sambuc 
84*433d6423SLionel Sambuc 				return r;
85*433d6423SLionel Sambuc 			}
86*433d6423SLionel Sambuc 
87*433d6423SLionel Sambuc 			count = 0;
88*433d6423SLionel Sambuc 		}
89*433d6423SLionel Sambuc 	} while (*pattern++);
90*433d6423SLionel Sambuc 
91*433d6423SLionel Sambuc 	if (count > 0)
92*433d6423SLionel Sambuc 		r = flush_buf(fd, buf, count * BLOCK_SIZE, write_size);
93*433d6423SLionel Sambuc 	else
94*433d6423SLionel Sambuc 		r = EXIT_SUCCESS;
95*433d6423SLionel Sambuc 
96*433d6423SLionel Sambuc 	free(buf);
97*433d6423SLionel Sambuc 
98*433d6423SLionel Sambuc 	return r;
99*433d6423SLionel Sambuc }
100*433d6423SLionel Sambuc 
read_pattern(int fd)101*433d6423SLionel Sambuc static int read_pattern(int fd)
102*433d6423SLionel Sambuc {
103*433d6423SLionel Sambuc 	char buf[BLOCK_SIZE];
104*433d6423SLionel Sambuc 	unsigned int i, val;
105*433d6423SLionel Sambuc 	ssize_t r;
106*433d6423SLionel Sambuc 
107*433d6423SLionel Sambuc 	for (;;) {
108*433d6423SLionel Sambuc 		memset(buf, '?', sizeof(buf));
109*433d6423SLionel Sambuc 
110*433d6423SLionel Sambuc 		if ((r = read(fd, buf, sizeof(buf))) != sizeof(buf)) {
111*433d6423SLionel Sambuc 			putchar('#');
112*433d6423SLionel Sambuc 
113*433d6423SLionel Sambuc 			if (!r) break; /* stop at hard EOF */
114*433d6423SLionel Sambuc 
115*433d6423SLionel Sambuc 			lseek(fd, sizeof(buf), SEEK_CUR);
116*433d6423SLionel Sambuc 
117*433d6423SLionel Sambuc 			continue;
118*433d6423SLionel Sambuc 		}
119*433d6423SLionel Sambuc 
120*433d6423SLionel Sambuc 		if (buf[0] == 'E' && buf[1] == 'O' && buf[2] == 'F') {
121*433d6423SLionel Sambuc 			for (i = 3; i < sizeof(buf); i++)
122*433d6423SLionel Sambuc 				if (buf[i] != 0) break;
123*433d6423SLionel Sambuc 
124*433d6423SLionel Sambuc 			if (i == sizeof(buf)) break;
125*433d6423SLionel Sambuc 		}
126*433d6423SLionel Sambuc 
127*433d6423SLionel Sambuc 		for (i = 1; i < sizeof(buf); i++)
128*433d6423SLionel Sambuc 			if (buf[i] != buf[0]) break;
129*433d6423SLionel Sambuc 
130*433d6423SLionel Sambuc 		if (i == sizeof(buf)) {
131*433d6423SLionel Sambuc 			switch (buf[0]) {
132*433d6423SLionel Sambuc 			case 'A':
133*433d6423SLionel Sambuc 			case 'B':
134*433d6423SLionel Sambuc 			case 'C':
135*433d6423SLionel Sambuc 			case 'D':
136*433d6423SLionel Sambuc 			case 'U':
137*433d6423SLionel Sambuc 			case '?':
138*433d6423SLionel Sambuc 				printf("%c", buf[0]);
139*433d6423SLionel Sambuc 				break;
140*433d6423SLionel Sambuc 
141*433d6423SLionel Sambuc 			case '\0':
142*433d6423SLionel Sambuc 				printf("0");
143*433d6423SLionel Sambuc 				break;
144*433d6423SLionel Sambuc 
145*433d6423SLionel Sambuc 			default:
146*433d6423SLionel Sambuc 				printf("X");
147*433d6423SLionel Sambuc 			}
148*433d6423SLionel Sambuc 
149*433d6423SLionel Sambuc 			continue;
150*433d6423SLionel Sambuc 		}
151*433d6423SLionel Sambuc 
152*433d6423SLionel Sambuc 		for (i = val = 0; i < sizeof(buf); i++)
153*433d6423SLionel Sambuc 			val += buf[i];
154*433d6423SLionel Sambuc 
155*433d6423SLionel Sambuc 		printf("%c", 'a' + val % 26);
156*433d6423SLionel Sambuc 	}
157*433d6423SLionel Sambuc 
158*433d6423SLionel Sambuc 	printf("\n");
159*433d6423SLionel Sambuc 
160*433d6423SLionel Sambuc 	return EXIT_SUCCESS;
161*433d6423SLionel Sambuc }
162*433d6423SLionel Sambuc 
main(int argc,char ** argv)163*433d6423SLionel Sambuc int main(int argc, char **argv)
164*433d6423SLionel Sambuc {
165*433d6423SLionel Sambuc 	int fd, r;
166*433d6423SLionel Sambuc 
167*433d6423SLionel Sambuc 	if (argc < 2) {
168*433d6423SLionel Sambuc 		fprintf(stderr, "usage: %s <device> [pattern [writesz]]\n",
169*433d6423SLionel Sambuc 			argv[0]);
170*433d6423SLionel Sambuc 
171*433d6423SLionel Sambuc 		return EXIT_FAILURE;
172*433d6423SLionel Sambuc 	}
173*433d6423SLionel Sambuc 
174*433d6423SLionel Sambuc 	fd = open(argv[1], (argc > 2) ? O_WRONLY : O_RDONLY);
175*433d6423SLionel Sambuc 	if (fd < 0) {
176*433d6423SLionel Sambuc 		perror("open");
177*433d6423SLionel Sambuc 
178*433d6423SLionel Sambuc 		return EXIT_FAILURE;
179*433d6423SLionel Sambuc 	}
180*433d6423SLionel Sambuc 
181*433d6423SLionel Sambuc 	if (argc > 2)
182*433d6423SLionel Sambuc 		r = write_pattern(fd, argv[2],
183*433d6423SLionel Sambuc 			argv[3] ? atoi(argv[3]) : BLOCK_SIZE);
184*433d6423SLionel Sambuc 	else
185*433d6423SLionel Sambuc 		r = read_pattern(fd);
186*433d6423SLionel Sambuc 
187*433d6423SLionel Sambuc 	close(fd);
188*433d6423SLionel Sambuc 
189*433d6423SLionel Sambuc 	return r;
190*433d6423SLionel Sambuc }
191