]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - tools/regression/lib/libc/stdio/test-fmemopen.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / tools / regression / lib / libc / stdio / test-fmemopen.c
1 /*-
2 Copyright (C) 2013 Pietro Cerutti <gahr@FreeBSD.org>
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 1. Redistributions of source code must retain the above copyright
8    notice, this list of conditions and the following disclaimer.
9 2. Redistributions in binary form must reproduce the above copyright
10    notice, this list of conditions and the following disclaimer in the
11    documentation and/or other materials provided with the distribution.
12
13 THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 SUCH DAMAGE.
24 */
25
26 /*
27  * Test basic FILE * functions (fread, fwrite, fseek, fclose) against
28  * a FILE * retrieved using fmemopen()
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <assert.h>
35 #include <errno.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <strings.h>
39
40 void
41 test_preexisting()
42 {
43         /* 
44          * Use a pre-existing buffer.
45          */
46
47         char buf[512];
48         char buf2[512];
49         char str[]  = "Test writing some stuff";
50         char str2[] = "AAAAAAAAA";
51         char str3[] = "AAAA writing some stuff";
52         FILE *fp;
53         size_t nofw, nofr;
54         int rc;
55
56         /* Open a FILE * using fmemopen. */
57         fp = fmemopen(buf, sizeof(buf), "w");
58         assert(fp != NULL);
59
60         /* Write to the buffer. */
61         nofw = fwrite(str, 1, sizeof(str), fp);
62         assert(nofw == sizeof(str));
63
64         /* Close the FILE *. */
65         rc = fclose(fp);
66         assert(rc == 0);
67
68         /* Re-open the FILE * to read back the data. */
69         fp = fmemopen(buf, sizeof(buf), "r");
70         assert(fp != NULL);
71
72         /* Read from the buffer. */
73         bzero(buf2, sizeof(buf2));
74         nofr = fread(buf2, 1, sizeof(buf2), fp);
75         assert(nofr == sizeof(buf2));
76
77         /* 
78          * Since a write on a FILE * retrieved by fmemopen
79          * will add a '\0' (if there's space), we can check
80          * the strings for equality.
81          */
82         assert(strcmp(str, buf2) == 0);
83
84         /* Close the FILE *. */
85         rc = fclose(fp);
86         assert(rc == 0);
87
88         /* Now open a FILE * on the first 4 bytes of the string. */
89         fp = fmemopen(str, 4, "w");
90         assert(fp != NULL);
91
92         /*
93          * Try to write more bytes than we shoud, we'll get a short count (4).
94          */
95         nofw = fwrite(str2, 1, sizeof(str2), fp);
96         assert(nofw == 4);
97
98         /* Close the FILE *. */
99         rc = fclose(fp);
100
101         /* Check that the string was not modified after the first 4 bytes. */
102         assert(strcmp(str, str3) == 0);
103 }
104
105 void
106 test_autoalloc()
107 {
108         /* 
109          * Let fmemopen allocate the buffer.
110          */
111
112         char str[] = "A quick test";
113         FILE *fp;
114         long pos;
115         size_t nofw, nofr, i;
116         int rc;
117
118         /* Open a FILE * using fmemopen. */
119         fp = fmemopen(NULL, 512, "w+");
120         assert(fp != NULL);
121
122         /* fill the buffer */
123         for (i = 0; i < 512; i++) {
124                 nofw = fwrite("a", 1, 1, fp);
125                 assert(nofw == 1);
126         }
127
128         /* Get the current position into the stream. */
129         pos = ftell(fp);
130         assert(pos == 512);
131
132         /* 
133          * Try to write past the end, we should get a short object count (0)
134          */
135         nofw = fwrite("a", 1, 1, fp);
136         assert(nofw == 0);
137
138         /* Close the FILE *. */
139         rc = fclose(fp);
140         assert(rc == 0);
141 }
142
143 void
144 test_data_length()
145 {
146         /*
147          * Here we test that a read operation doesn't go past the end of the
148          * data actually written, and that a SEEK_END seeks from the end of the
149          * data, not of the whole buffer.
150          */
151         FILE *fp;
152         char buf[512] = {'\0'};
153         char str[]  = "Test data length. ";
154         char str2[] = "Do we have two sentences?";
155         char str3[sizeof(str) + sizeof(str2) -1];
156         long pos;
157         size_t nofw, nofr;
158         int rc;
159
160         /* Open a FILE * for updating our buffer. */
161         fp = fmemopen(buf, sizeof(buf), "w+");
162         assert(fp != NULL);
163
164         /* Write our string into the buffer. */
165         nofw = fwrite(str, 1, sizeof(str), fp);
166         assert(nofw == sizeof(str));
167
168         /* 
169          * Now seek to the end and check that ftell
170          * gives us sizeof(str).
171          */
172         rc = fseek(fp, 0, SEEK_END);
173         assert(rc == 0);
174         pos = ftell(fp);
175         assert(pos == sizeof(str));
176
177         /* Close the FILE *. */
178         rc = fclose(fp);
179         assert(rc == 0);
180
181         /* Reopen the buffer for appending. */
182         fp = fmemopen(buf, sizeof(buf), "a+");
183         assert(fp != NULL);
184
185         /* We should now be writing after the first string. */
186         nofw = fwrite(str2, 1, sizeof(str2), fp);
187         assert(nofw == sizeof(str2));
188
189         /* Rewind the FILE *. */
190         rc = fseek(fp, 0, SEEK_SET);
191         assert(rc == 0);
192
193         /* Make sure we're at the beginning. */
194         pos = ftell(fp);
195         assert(pos == 0);
196
197         /* Read the whole buffer. */
198         nofr = fread(str3, 1, sizeof(buf), fp);
199         assert(nofr == sizeof(str3));
200
201         /* Make sure the two strings are there. */
202         assert(strncmp(str3, str, sizeof(str) - 1) == 0);
203         assert(strncmp(str3 + sizeof(str) - 1, str2, sizeof(str2)) == 0);
204
205         /* Close the FILE *. */
206         rc = fclose(fp);
207         assert(rc == 0);
208 }
209
210 void
211 test_binary()
212 {
213         /*
214          * Make sure that NULL bytes are never appended when opening a buffer
215          * in binary mode.
216          */
217
218         FILE *fp;
219         char buf[20];
220         char str[] = "Test";
221         size_t nofw;
222         int rc, i;
223
224         /* Pre-fill the buffer. */
225         memset(buf, 'A', sizeof(buf));
226
227         /* Open a FILE * in binary mode. */
228         fp = fmemopen(buf, sizeof(buf), "w+b");
229         assert(fp != NULL);
230
231         /* Write some data into it. */
232         nofw = fwrite(str, 1, strlen(str), fp);
233         assert(nofw == strlen(str));
234
235         /* Make sure that the buffer doesn't contain any NULL bytes. */
236         for (i = 0; i < sizeof(buf); i++)
237                 assert(buf[i] != '\0');
238
239         /* Close the FILE *. */
240         rc = fclose(fp);
241         assert(rc == 0);
242 }
243
244 int
245 main(void)
246 {
247         test_autoalloc();
248         test_preexisting();
249         test_data_length();
250         test_binary();
251         return (0);
252 }