test: Add file loading support
[libisds.git] / test / test.c
blob6ff2301f36598a3634643bef04dd971228d00972
1 #ifndef __ISDS_TEST_H
2 #define __ISDS_TEST_H
4 #define _XOPEN_SOURCE 500
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <stdint.h>
8 #include <stdarg.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <sys/mman.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <unistd.h>
18 /* Print formated string into automtically reallocated @uffer.
19 * @buffer automatically reallocated buffer. Must be &NULL or preallocated
20 * memory.
21 * @format format string as for printf(3)
22 * @ap list of variadic arguments, after call will be in udefined state
23 * @Returns number of bytes printed. In case of errror, -1 and NULL @buffer*/
24 int test_vasprintf(char **buffer, const char *format, va_list ap) {
25 va_list aq;
26 int length, new_length;
27 char *new_buffer;
29 if (!buffer || !format) {
30 if (buffer) {
31 free(*buffer);
32 *buffer = NULL;
34 return -1;
37 va_copy(aq, ap);
38 length = vsnprintf(NULL, 0, format, aq) + 1;
39 va_end(aq);
40 if (length <= 0) {
41 free(*buffer);
42 *buffer = NULL;
43 return -1;
46 new_buffer = realloc(*buffer, length);
47 if (!new_buffer) {
48 free(*buffer);
49 *buffer = NULL;
50 return -1;
52 *buffer = new_buffer;
54 new_length = vsnprintf(*buffer, length, format, ap);
55 if (new_length >= length) {
56 free(*buffer);
57 *buffer = NULL;
58 return -1;
61 return new_length;
65 /* Print formated string into automtically reallocated @uffer.
66 * @buffer automatically reallocated buffer. Must be &NULL or preallocated
67 * memory.
68 * @format format string as for printf(3)
69 * @... variadic arguments
70 * @Returns number of bytes printed. In case of errror, -1 and NULL @buffer*/
71 int test_asprintf(char **buffer, const char *format, ...) {
72 int ret;
73 va_list ap;
74 va_start(ap, format);
75 ret = test_vasprintf(buffer, format, ap);
76 va_end(ap);
77 return ret;
81 int test_mmap_file(const char *file, int *fd, void **buffer, size_t *length) {
82 struct stat file_info;
84 if (!file || !fd || !buffer || !length) return -1;
87 *fd = open(file, O_RDONLY);
88 if (*fd == -1) {
89 fprintf(stderr, "%s: Could not open file: %s\n", file, strerror(errno));
90 return -1;
93 if (-1 == fstat(*fd, &file_info)) {
94 fprintf(stderr, "%s: Could not get file size: %s\n", file,
95 strerror(errno));
96 close(*fd);
97 return -1;
99 if (file_info.st_size < 0) {
100 fprintf(stderr, "File `%s' has negative size: %jd\n", file,
101 (intmax_t) file_info.st_size);
102 close(*fd);
103 return -1;
105 *length = file_info.st_size;
107 *buffer = mmap(NULL, *length, PROT_READ, MAP_PRIVATE, *fd, 0);
108 if (*buffer == MAP_FAILED) {
109 fprintf(stderr, "%s: Could not map file to memory: %s\n", file,
110 strerror(errno));
111 close(*fd);
112 return -1;
115 return 0;
119 int test_munmap_file(int fd, void *buffer, size_t length) {
120 int err = 0;
121 long int page_size = sysconf(_SC_PAGE_SIZE);
122 size_t pages = (length % page_size) ?
123 ((length / page_size) + 1) * page_size:
124 length;
126 err = munmap(buffer, pages);
127 if (err) {
128 fprintf(stderr, "Could not unmap memory at %p and length %zu: %s\n",
129 buffer, pages, strerror(errno));
132 err = close(fd);
133 if (err) {
134 fprintf(stderr, "Could close file descriptor %d: %s\n", fd,
135 strerror(errno));
138 return err;
141 #endif