]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - lib/libc/tests/stdio/mkostemp_test.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / lib / libc / tests / stdio / mkostemp_test.c
1 /*-
2  * Copyright (c) 2013 Jilles Tjoelker
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  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 /*
28  * Test program for mkostemp().
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <sys/stat.h>
35
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <paths.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43
44 #include <atf-c.h>
45
46 static const char template[] = "mkostemp.XXXXXXXX";
47 static int testnum;
48
49 #define MISCFLAGS (O_APPEND | O_DIRECT | O_SHLOCK | O_EXLOCK | O_SYNC)
50
51 static void
52 test_one(int oflags)
53 {
54         char tmpf[sizeof(template)];
55         struct stat st1, st2;
56         int fd;
57
58         memcpy(tmpf, template, sizeof(tmpf));
59         fd = mkostemp(tmpf, oflags);
60         if (fd < 0) {
61                 printf("not ok %d - oflags=%#x "
62                     "mkostemp() reported failure: %s\n",
63                     testnum++, oflags, strerror(errno));
64                 return;
65         }
66         if (memcmp(tmpf, template, sizeof(tmpf) - 8 - 1) != 0) {
67                 printf("not ok %d - oflags=%#x "
68                     "returned pathname does not match template: %s\n",
69                     testnum++, oflags, tmpf);
70                 return;
71         }
72         do {
73                 if (fcntl(fd, F_GETFD) !=
74                     (oflags & O_CLOEXEC ? FD_CLOEXEC : 0)) {
75                         printf("not ok %d - oflags=%#x "
76                             "close-on-exec flag incorrect\n",
77                             testnum++, oflags);
78                         break;
79                 }
80                 if ((fcntl(fd, F_GETFL) & MISCFLAGS) != (oflags & MISCFLAGS)) {
81                         printf("not ok %d - oflags=%#x "
82                             "open flags incorrect\n",
83                             testnum++, oflags);
84                         break;
85                 }
86                 if (stat(tmpf, &st1) == -1) {
87                         printf("not ok %d - oflags=%#x "
88                             "cannot stat returned pathname %s: %s\n",
89                             testnum++, oflags, tmpf, strerror(errno));
90                         break;
91                 }
92                 if (fstat(fd, &st2) == -1) {
93                         printf("not ok %d - oflags=%#x "
94                             "cannot fstat returned fd %d: %s\n",
95                             testnum++, oflags, fd, strerror(errno));
96                         break;
97                 }
98                 if (!S_ISREG(st1.st_mode) || (st1.st_mode & 0777) != 0600 ||
99                     st1.st_nlink != 1 || st1.st_size != 0) {
100                         printf("not ok %d - oflags=%#x "
101                             "named file attributes incorrect\n",
102                             testnum++, oflags);
103                         break;
104                 }
105                 if (!S_ISREG(st2.st_mode) || (st2.st_mode & 0777) != 0600 ||
106                     st2.st_nlink != 1 || st2.st_size != 0) {
107                         printf("not ok %d - oflags=%#x "
108                             "opened file attributes incorrect\n",
109                             testnum++, oflags);
110                         break;
111                 }
112                 if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
113                         printf("not ok %d - oflags=%#x "
114                             "named and opened file do not match\n",
115                             testnum++, oflags);
116                         break;
117                 }
118                 (void)unlink(tmpf);
119                 if (fstat(fd, &st2) == -1)
120                         printf("not ok %d - oflags=%#x "
121                             "cannot fstat returned fd %d again: %s\n",
122                             testnum++, oflags, fd, strerror(errno));
123                 else if (st2.st_nlink != 0)
124                         printf("not ok %d - oflags=%#x "
125                             "st_nlink is not 0 after unlink\n",
126                             testnum++, oflags);
127                 else
128                         printf("ok %d - oflags=%#x\n", testnum++, oflags);
129                 (void)close(fd);
130                 return;
131         } while (0);
132         (void)close(fd);
133         (void)unlink(tmpf);
134 }
135
136 ATF_TC_WITHOUT_HEAD(zero);
137 ATF_TC_BODY(zero, tc)
138 {
139
140         test_one(0);
141 }
142
143 ATF_TC_WITHOUT_HEAD(O_CLOEXEC);
144 ATF_TC_BODY(O_CLOEXEC, tc)
145 {
146
147         test_one(O_CLOEXEC);
148 }
149
150 ATF_TC_WITHOUT_HEAD(O_APPEND);
151 ATF_TC_BODY(O_APPEND, tc)
152 {
153
154         test_one(O_APPEND);
155 }
156
157 ATF_TC_WITHOUT_HEAD(O_APPEND__O_CLOEXEC);
158 ATF_TC_BODY(O_APPEND__O_CLOEXEC, tc)
159 {
160
161         test_one(O_APPEND|O_CLOEXEC);
162 }
163
164 ATF_TC_WITHOUT_HEAD(bad_flags);
165 ATF_TC_BODY(bad_flags, tc)
166 {
167
168         char tmpf[sizeof(template)];
169
170         memcpy(tmpf, template, sizeof(tmpf));
171         ATF_REQUIRE_MSG(mkostemp(tmpf, O_CREAT) == -1,
172                 "mkostemp(O_CREAT) succeeded unexpectedly");
173 }
174
175 ATF_TP_ADD_TCS(tp)
176 {
177
178         ATF_TP_ADD_TC(tp, zero);
179         ATF_TP_ADD_TC(tp, O_CLOEXEC);
180         ATF_TP_ADD_TC(tp, O_APPEND);
181         ATF_TP_ADD_TC(tp, O_APPEND__O_CLOEXEC);
182         ATF_TP_ADD_TC(tp, bad_flags);
183
184         return (atf_no_error());
185 }