xref: /haiku/src/tests/system/libroot/posix/seek_and_write_test.cpp (revision c90684742e7361651849be4116d0e5de3a817194)
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