Add forgotten doc/Makefile.am
[libisds.git] / test / test.c
blob542ce8793d72bae30f0ee95d6a15f15cfb96c77a
1 #define _XOPEN_SOURCE 500
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <stdarg.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
10 #ifndef _WIN32
11 #include <sys/mman.h>
12 #endif
14 #include <errno.h>
15 #include <string.h>
16 #include <unistd.h>
19 /* Print formated string into automtically reallocated @uffer.
20 * @buffer automatically reallocated buffer. Must be &NULL or preallocated
21 * memory.
22 * @format format string as for printf(3)
23 * @ap list of variadic arguments, after call will be in udefined state
24 * @Returns number of bytes printed. In case of errror, -1 and NULL @buffer */
25 int test_vasprintf(char **buffer, const char *format, va_list ap) {
26 va_list aq;
27 int length, new_length;
28 char *new_buffer;
30 if (!buffer || !format) {
31 if (buffer) {
32 free(*buffer);
33 *buffer = NULL;
35 return -1;
38 va_copy(aq, ap);
39 length = vsnprintf(NULL, 0, format, aq) + 1;
40 va_end(aq);
41 if (length <= 0) {
42 free(*buffer);
43 *buffer = NULL;
44 return -1;
47 new_buffer = realloc(*buffer, length);
48 if (!new_buffer) {
49 free(*buffer);
50 *buffer = NULL;
51 return -1;
53 *buffer = new_buffer;
55 new_length = vsnprintf(*buffer, length, format, ap);
56 if (new_length >= length) {
57 free(*buffer);
58 *buffer = NULL;
59 return -1;
62 return new_length;
66 /* Print formated string into automtically reallocated @uffer.
67 * @buffer automatically reallocated buffer. Must be &NULL or preallocated
68 * memory.
69 * @format format string as for printf(3)
70 * @... variadic arguments
71 * @Returns number of bytes printed. In case of errror, -1 and NULL @buffer */
72 int test_asprintf(char **buffer, const char *format, ...) {
73 int ret;
74 va_list ap;
75 va_start(ap, format);
76 ret = test_vasprintf(buffer, format, ap);
77 va_end(ap);
78 return ret;
82 #ifdef _WIN32
83 int test_mmap_file(const char *file, int *fd, void **buffer, size_t *length) {
84 struct stat file_info;
85 int ret, pos = 0;
87 if (!file || !fd || !buffer || !length) return -1;
89 *fd = open(file, O_RDONLY);
90 if (*fd == -1) {
91 fprintf(stderr, "%s: Could not open file: %s\n", file, strerror(errno));
92 return -1;
95 if (-1 == fstat(*fd, &file_info)) {
96 fprintf(stderr, "%s: Could not get file size: %s\n", file,
97 strerror(errno));
98 close(*fd);
99 return -1;
101 if (file_info.st_size < 0) {
102 fprintf(stderr, "File `%s' has negative size: %jd\n", file,
103 (intmax_t) file_info.st_size);
104 close(*fd);
105 return -1;
107 *length = file_info.st_size;
108 *buffer = malloc(*length);
110 if (!*buffer) {
111 fprintf(stderr, "%s: Could not allocate memory for file mapping: %s\n",
112 file, strerror(errno));
113 close(*fd);
114 return -1;
117 do {
118 ret = read(*fd, *buffer + pos, *length - pos);
120 if (ret > 0) {
121 pos += ret;
123 } while ((ret < 0 && errno == EINTR) || (ret > 0 && pos < *length));
125 if (ret < 0) {
126 fprintf(stderr, "%s: Could not map file to memory: %s\n", file,
127 strerror(errno));
128 free(*buffer);
129 *buffer = NULL;
130 close(*fd);
131 return -1;
134 return 0;
137 int test_munmap_file(int fd, void *buffer, size_t length) {
138 int err = 0;
139 free(buffer);
141 err = close(fd);
142 if (err) {
143 fprintf(stderr, "Could close file descriptor %d: %s\n", fd,
144 strerror(errno));
147 return err;
149 #else
150 int test_mmap_file(const char *file, int *fd, void **buffer, size_t *length) {
151 struct stat file_info;
153 if (!file || !fd || !buffer || !length) return -1;
156 *fd = open(file, O_RDONLY);
157 if (*fd == -1) {
158 fprintf(stderr, "%s: Could not open file: %s\n", file, strerror(errno));
159 return -1;
162 if (-1 == fstat(*fd, &file_info)) {
163 fprintf(stderr, "%s: Could not get file size: %s\n", file,
164 strerror(errno));
165 close(*fd);
166 return -1;
168 if (file_info.st_size < 0) {
169 fprintf(stderr, "File `%s' has negative size: %jd\n", file,
170 (intmax_t) file_info.st_size);
171 close(*fd);
172 return -1;
174 *length = file_info.st_size;
176 *buffer = mmap(NULL, *length, PROT_READ, MAP_PRIVATE, *fd, 0);
177 if (*buffer == MAP_FAILED) {
178 fprintf(stderr, "%s: Could not map file to memory: %s\n", file,
179 strerror(errno));
180 close(*fd);
181 return -1;
184 return 0;
188 int test_munmap_file(int fd, void *buffer, size_t length) {
189 int err = 0;
190 long int page_size = sysconf(_SC_PAGE_SIZE);
191 size_t pages = (length % page_size) ?
192 ((length / page_size) + 1) * page_size:
193 length;
195 err = munmap(buffer, pages);
196 if (err) {
197 fprintf(stderr, "Could not unmap memory at %p and length %zu: %s\n",
198 buffer, pages, strerror(errno));
201 err = close(fd);
202 if (err) {
203 fprintf(stderr, "Could close file descriptor %d: %s\n", fd,
204 strerror(errno));
207 return err;
209 #endif