source: mainline/uspace/lib/c/test/stdio.c@ eec201d

Last change on this file since eec201d was 7ab7075f, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Add support for 'x' fopen file mode modifier from C11.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * Copyright (c) 2018 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Test stdio module
35 */
36
37#include <errno.h>
38#include <pcut/pcut.h>
39#include <stdio.h>
40#include <str.h>
41#include <tmpfile.h>
42#include <vfs/vfs.h>
43
44PCUT_INIT;
45
46PCUT_TEST_SUITE(stdio);
47
48/** remove function */
49PCUT_TEST(remove)
50{
51 char buf[L_tmpnam];
52 char *p;
53 FILE *f;
54 int rc;
55
56 /* Generate unique file name */
57 p = tmpnam(buf);
58 PCUT_ASSERT_NOT_NULL(p);
59
60 /* Removing it should fail */
61 rc = remove(buf);
62 PCUT_ASSERT_TRUE(rc != 0);
63
64 f = fopen(buf, "wx");
65 PCUT_ASSERT_NOT_NULL(f);
66 fclose(f);
67
68 /* Remove for the first time */
69 rc = remove(buf);
70 PCUT_ASSERT_INT_EQUALS(0, rc);
71
72 /* Should fail the second time */
73 rc = remove(buf);
74 PCUT_ASSERT_TRUE(rc != 0);
75}
76
77/** rename function */
78PCUT_TEST(rename)
79{
80 char buf1[L_tmpnam];
81 char buf2[L_tmpnam];
82 char *p;
83 FILE *f;
84 int rc;
85
86 /* Generate first unique file name */
87 p = tmpnam(buf1);
88 PCUT_ASSERT_NOT_NULL(p);
89
90 /* Generate second unique file name */
91 p = tmpnam(buf2);
92 PCUT_ASSERT_NOT_NULL(p);
93
94 f = fopen(buf1, "wx");
95 PCUT_ASSERT_NOT_NULL(f);
96 fclose(f);
97
98 /* Rename to the second name */
99 rc = rename(buf1, buf2);
100 PCUT_ASSERT_INT_EQUALS(0, rc);
101
102 /* First name should no longer exist */
103 rc = remove(buf1);
104 PCUT_ASSERT_TRUE(rc != 0);
105
106 /* Second can be removed */
107 rc = remove(buf2);
108 PCUT_ASSERT_INT_EQUALS(0, rc);
109}
110
111/** tmpfile function */
112PCUT_TEST(tmpfile)
113{
114 FILE *f;
115 char c;
116 size_t n;
117
118 f = tmpfile();
119 PCUT_ASSERT_NOT_NULL(f);
120
121 c = 'x';
122 n = fwrite(&c, sizeof(c), 1, f);
123 PCUT_ASSERT_INT_EQUALS(1, n);
124
125 rewind(f);
126 c = '\0';
127 n = fread(&c, sizeof(c), 1, f);
128 PCUT_ASSERT_INT_EQUALS(1, n);
129 PCUT_ASSERT_INT_EQUALS('x', c);
130
131 fclose(f);
132}
133
134/** tmpnam function with buffer argument */
135PCUT_TEST(tmpnam_buf)
136{
137 char buf[L_tmpnam];
138 char *p;
139 FILE *f;
140
141 p = tmpnam(buf);
142 PCUT_ASSERT_NOT_NULL(p);
143
144 f = fopen(p, "w+x");
145 PCUT_ASSERT_NOT_NULL(f);
146 (void) remove(p);
147 fclose(f);
148}
149
150/** tmpnam function called twice */
151PCUT_TEST(tmpnam_twice)
152{
153 char buf1[L_tmpnam];
154 char buf2[L_tmpnam];
155 char *p;
156
157 p = tmpnam(buf1);
158 PCUT_ASSERT_NOT_NULL(p);
159
160 p = tmpnam(buf2);
161 PCUT_ASSERT_NOT_NULL(p);
162
163 /* We must get two distinct names */
164 PCUT_ASSERT_TRUE(str_cmp(buf1, buf2) != 0);
165}
166
167/** tmpnam function with NULL argument */
168PCUT_TEST(tmpnam_null)
169{
170 char *p;
171 FILE *f;
172
173 p = tmpnam(NULL);
174 PCUT_ASSERT_NOT_NULL(p);
175
176 f = fopen(p, "w+x");
177 PCUT_ASSERT_NOT_NULL(f);
178 (void) remove(p);
179 fclose(f);
180}
181
182/** fgetpos and fsetpos functions */
183PCUT_TEST(fgetpos_setpos)
184{
185 fpos_t pos;
186 int rc;
187 FILE *f;
188
189 f = tmpfile();
190 PCUT_ASSERT_NOT_NULL(f);
191
192 rc = fputs("abc", f);
193 PCUT_ASSERT_TRUE(rc >= 0);
194
195 rc = fgetpos(f, &pos);
196 PCUT_ASSERT_TRUE(rc >= 0);
197
198 rewind(f);
199
200 rc = fsetpos(f, &pos);
201 PCUT_ASSERT_TRUE(rc >= 0);
202
203 (void) fclose(f);
204}
205
206/** perror function with NULL as argument */
207PCUT_TEST(perror_null_msg)
208{
209 errno = EINVAL;
210 perror(NULL);
211}
212
213/** perror function with empty string as argument */
214PCUT_TEST(perror_empty_msg)
215{
216 errno = EINVAL;
217 perror("");
218}
219
220/** perror function with a message argument */
221PCUT_TEST(perror_msg)
222{
223 errno = EINVAL;
224 perror("This is a test");
225}
226
227PCUT_EXPORT(stdio);
Note: See TracBrowser for help on using the repository browser.