Deleted Added
full compact
fifo_create.c (149959) fifo_create.c (179934)
1/*-
1/*-
2 * Copyright (c) 2005 Robert N. M. Watson
2 * Copyright (c) 2005-2008 Robert N. M. Watson
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

--- 7 unchanged lines hidden (view full) ---

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 *
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

--- 7 unchanged lines hidden (view full) ---

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 * $FreeBSD: head/tools/regression/fifo/fifo_create/fifo_create.c 149959 2005-09-10 21:09:26Z rwatson $
26 * $FreeBSD: head/tools/regression/fifo/fifo_create/fifo_create.c 179934 2008-06-22 21:03:26Z rwatson $
27 */
28
29#include <sys/stat.h>
30
31#include <err.h>
32#include <errno.h>
33#include <limits.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unistd.h>
38
39/*
40 * Simple regression test for the creation and destruction of POSIX fifos in
41 * the file system name space. Using a specially created directory, create
42 * a fifo in it and check that the following properties are present, as
43 * specified in IEEE Std 1003.1, 2004 Edition:
44 *
27 */
28
29#include <sys/stat.h>
30
31#include <err.h>
32#include <errno.h>
33#include <limits.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unistd.h>
38
39/*
40 * Simple regression test for the creation and destruction of POSIX fifos in
41 * the file system name space. Using a specially created directory, create
42 * a fifo in it and check that the following properties are present, as
43 * specified in IEEE Std 1003.1, 2004 Edition:
44 *
45 * - When mkfifo() is called, on success, a fifo is created.
45 * - When mkfifo() or mknod(S_IFIFO) is called, on success, a fifo is
46 * created.
46 *
47 * - On an error, no fifo is created. (XXX: Not tested)
48 *
49 * - The mode bits on the fifo are a product of combining the umask and
50 * requested mode.
51 *
52 * - The fifo's owner will be the processes effective user ID. (XXX: Not
53 * tested)

--- 25 unchanged lines hidden (view full) ---

79static void __unused
80atexit_temp_dir(void)
81{
82
83 rmdir(temp_dir);
84}
85
86/*
47 *
48 * - On an error, no fifo is created. (XXX: Not tested)
49 *
50 * - The mode bits on the fifo are a product of combining the umask and
51 * requested mode.
52 *
53 * - The fifo's owner will be the processes effective user ID. (XXX: Not
54 * tested)

--- 25 unchanged lines hidden (view full) ---

80static void __unused
81atexit_temp_dir(void)
82{
83
84 rmdir(temp_dir);
85}
86
87/*
87 * Basic creation tests: verify that mkfifo() creates a fifo, that the time
88 * stamps on the directory are updated, that if we try twice we get EEXIST,
89 * and that we can unlink it.
88 * Basic creation tests: verify that mkfifo(2) (or mknod(2)) creates a fifo,
89 * that the time stamps on the directory are updated, that if we try twice we
90 * get EEXIST, and that we can unlink it.
90 */
91static void
91 */
92static void
92fifo_create_test(void)
93fifo_create_test(int use_mkfifo)
93{
94 struct stat old_dirsb, dirsb, fifosb;
94{
95 struct stat old_dirsb, dirsb, fifosb;
96 const char *testname;
95 char path[PATH_MAX];
96 int error;
97
97 char path[PATH_MAX];
98 int error;
99
100 if (use_mkfifo)
101 testname = "mkfifo";
102 else
103 testname = "mknod";
104
98 /*
99 * Sleep to make sure that the time stamp on the directory will be
100 * updated.
101 */
105 /*
106 * Sleep to make sure that the time stamp on the directory will be
107 * updated.
108 */
102 sleep(2);
103
104 if (stat(temp_dir, &old_dirsb) < 0)
109 if (stat(temp_dir, &old_dirsb) < 0)
105 err(-1, "basic_create_test: stat: %s", temp_dir);
110 err(-1, "basic_create_test: %s: stat: %s", testname,
111 temp_dir);
106
112
113 sleep(2);
114
107 snprintf(path, PATH_MAX, "%s/testfifo", temp_dir);
108
115 snprintf(path, PATH_MAX, "%s/testfifo", temp_dir);
116
109 if (mkfifo(path, 0600) < 0)
110 err(-1, "basic_create_test: mkfifo: %s", path);
117 if (use_mkfifo) {
118 if (mkfifo(path, 0600) < 0)
119 err(-1, "basic_create_test: %s: %s", testname, path);
120 } else {
121 if (mknod(path, S_IFIFO | 0600, 0) < 0)
122 err(-1, "basic_create_test: %s: %s", testname, path);
123 }
111
112 if (stat(path, &fifosb) < 0) {
113 error = errno;
114 (void)unlink(path);
115 errno = error;
124
125 if (stat(path, &fifosb) < 0) {
126 error = errno;
127 (void)unlink(path);
128 errno = error;
116 err(-1, "basic_create_test: stat: %s", path);
129 err(-1, "basic_create_test: %s: stat: %s", testname, path);
117 }
118
119 if (!(S_ISFIFO(fifosb.st_mode))) {
120 (void)unlink(path);
130 }
131
132 if (!(S_ISFIFO(fifosb.st_mode))) {
133 (void)unlink(path);
121 errx(-1, "basic_create_test: mkfifo produced non-fifo");
134 errx(-1, "basic_create_test: %s produced non-fifo",
135 testname);
122 }
123
136 }
137
124 if (mkfifo(path, 0600) == 0)
125 errx(-1, "basic_create_test: dup mkfifo succeeded");
138 if (use_mkfifo) {
139 if (mkfifo(path, 0600) == 0)
140 errx(-1, "basic_create_test: dup %s succeeded",
141 testname);
142 } else {
143 if (mknod(path, S_IFIFO | 0600, 0) == 0)
144 errx(-1, "basic_create_test: dup %s succeeded",
145 testname);
146 }
126
127 if (errno != EEXIST)
147
148 if (errno != EEXIST)
128 err(-1, "basic_create_test: dup mkfifo unexpected error");
149 err(-1, "basic_create_test: dup %s unexpected error",
150 testname);
129
130 if (stat(temp_dir, &dirsb) < 0) {
131 error = errno;
132 (void)unlink(path);
133 errno = error;
151
152 if (stat(temp_dir, &dirsb) < 0) {
153 error = errno;
154 (void)unlink(path);
155 errno = error;
134 err(-1, "basic_create_test: stat: %s", temp_dir);
156 err(-1, "basic_create_test: %s: stat: %s", testname,
157 temp_dir);
135 }
136
137 if (old_dirsb.st_ctime == dirsb.st_ctime) {
138 (void)unlink(path);
158 }
159
160 if (old_dirsb.st_ctime == dirsb.st_ctime) {
161 (void)unlink(path);
139 errx(-1, "basic_create_test: old_dirsb.st_ctime == "
140 "dirsb.st_ctime");
162 errx(-1, "basic_create_test: %s: old_dirsb.st_ctime == "
163 "dirsb.st_ctime", testname);
141 }
142
143 if (old_dirsb.st_mtime == dirsb.st_mtime) {
144 (void)unlink(path);
164 }
165
166 if (old_dirsb.st_mtime == dirsb.st_mtime) {
167 (void)unlink(path);
145 errx(-1, "basic_create_test: old_dirsb.st_mtime == "
146 "dirsb.st_mtime");
168 errx(-1, "basic_create_test: %s: old_dirsb.st_mtime == "
169 "dirsb.st_mtime", testname);
147 }
148
149 if (unlink(path) < 0)
170 }
171
172 if (unlink(path) < 0)
150 err(-1, "basic_create_test: unlink: %s", path);
173 err(-1, "basic_create_test: %s: unlink: %s", testname, path);
151
152 if (stat(path, &fifosb) == 0)
174
175 if (stat(path, &fifosb) == 0)
153 errx(-1, "basic_create_test: unlink failed to unlink");
176 errx(-1, "basic_create_test: %s: unlink failed to unlink",
177 testname);
154 if (errno != ENOENT)
178 if (errno != ENOENT)
155 err(-1, "basic_create_test: unlink unexpected error");
179 err(-1, "basic_create_test: %s: unlink unexpected error",
180 testname);
156}
157
158/*
159 * Having determined that basic create/remove/etc functionality is present
160 * for fifos, now make sure that the umask, requested permissions, and
161 * resulting mode are handled properly.
162 */
163static const struct permission_test {

--- 7 unchanged lines hidden (view full) ---

171 S_IRWXO },
172 {0077, S_IRWXU, S_IFIFO | S_IRWXU},
173 {0077, S_IRWXU | S_IRWXG | S_IRWXO, S_IFIFO | S_IRWXU},
174};
175static const int permission_test_count = sizeof(permission_test) /
176 sizeof(struct permission_test);
177
178static void
181}
182
183/*
184 * Having determined that basic create/remove/etc functionality is present
185 * for fifos, now make sure that the umask, requested permissions, and
186 * resulting mode are handled properly.
187 */
188static const struct permission_test {

--- 7 unchanged lines hidden (view full) ---

196 S_IRWXO },
197 {0077, S_IRWXU, S_IFIFO | S_IRWXU},
198 {0077, S_IRWXU | S_IRWXG | S_IRWXO, S_IFIFO | S_IRWXU},
199};
200static const int permission_test_count = sizeof(permission_test) /
201 sizeof(struct permission_test);
202
203static void
179fifo_permission_test(void)
204fifo_permission_test(int use_mkfifo)
180{
181 const struct permission_test *ptp;
182 mode_t __unused old_umask;
183 char path[PATH_MAX];
205{
206 const struct permission_test *ptp;
207 mode_t __unused old_umask;
208 char path[PATH_MAX];
209 const char *testname;
184 struct stat sb;
185 int error, i;
186
210 struct stat sb;
211 int error, i;
212
213 if (use_mkfifo)
214 testname = "mkfifo";
215 else
216 testname = "mknod";
217
187 snprintf(path, PATH_MAX, "%s/testfifo", temp_dir);
188 old_umask = umask(0022);
189 for (i = 0; i < permission_test_count; i++) {
190 ptp = &permission_test[i];
191
192 umask(ptp->pt_umask);
218 snprintf(path, PATH_MAX, "%s/testfifo", temp_dir);
219 old_umask = umask(0022);
220 for (i = 0; i < permission_test_count; i++) {
221 ptp = &permission_test[i];
222
223 umask(ptp->pt_umask);
193 if (mkfifo(path, ptp->pt_reqmode) < 0)
194 err(-1, "fifo_permission_test: %08o %08o %08o\n",
195 ptp->pt_umask, ptp->pt_reqmode, ptp->pt_mode);
224 if (use_mkfifo) {
225 if (mkfifo(path, ptp->pt_reqmode) < 0)
226 err(-1, "fifo_permission_test: %s: %08o "
227 "%08o %08o\n", testname, ptp->pt_umask,
228 ptp->pt_reqmode, ptp->pt_mode);
229 } else {
230 if (mknod(path, S_IFIFO | ptp->pt_reqmode, 0) < 0)
231 err(-1, "fifo_permission_test: %s: %08o "
232 "%08o %08o\n", testname, ptp->pt_umask,
233 ptp->pt_reqmode, ptp->pt_mode);
234 }
196
197 if (stat(path, &sb) < 0) {
198 error = errno;
199 (void)unlink(path);
200 errno = error;
235
236 if (stat(path, &sb) < 0) {
237 error = errno;
238 (void)unlink(path);
239 errno = error;
201 err(-1, "fifo_permission_test: %s", path);
240 err(-1, "fifo_permission_test: %s: %s", testname,
241 path);
202 }
203
204 if (sb.st_mode != ptp->pt_mode) {
205 (void)unlink(path);
242 }
243
244 if (sb.st_mode != ptp->pt_mode) {
245 (void)unlink(path);
206 errx(-1, "fifo_permission_test: %08o %08o %08o "
207 "got %08o", ptp->pt_umask, ptp->pt_reqmode,
208 ptp->pt_mode, sb.st_mode);
246 errx(-1, "fifo_permission_test: %s: %08o %08o %08o "
247 "got %08o", testname, ptp->pt_umask,
248 ptp->pt_reqmode, ptp->pt_mode, sb.st_mode);
209 }
210
211 if (unlink(path) < 0)
249 }
250
251 if (unlink(path) < 0)
212 err(-1, "fifo_permission_test: unlink: %s", path);
252 err(-1, "fifo_permission_test: %s: unlink: %s",
253 testname, path);
213 }
214 umask(old_umask);
215}
216
217int
218main(int argc, char *argv[])
219{
254 }
255 umask(old_umask);
256}
257
258int
259main(int argc, char *argv[])
260{
261 int i;
220
221 if (geteuid() != 0)
222 errx(-1, "must be run as root");
223
224 strcpy(temp_dir, "/tmp/fifo_create.XXXXXXXXXXX");
225 if (mkdtemp(temp_dir) == NULL)
226 err(-1, "mkdtemp");
227 atexit(atexit_temp_dir);
228
229 if (chdir(temp_dir) < 0)
230 err(-1, "chdir");
231
262
263 if (geteuid() != 0)
264 errx(-1, "must be run as root");
265
266 strcpy(temp_dir, "/tmp/fifo_create.XXXXXXXXXXX");
267 if (mkdtemp(temp_dir) == NULL)
268 err(-1, "mkdtemp");
269 atexit(atexit_temp_dir);
270
271 if (chdir(temp_dir) < 0)
272 err(-1, "chdir");
273
232 fifo_create_test();
274 /*
275 * Run each test twice, once with mknod(2) and a second time with
276 * mkfifo(2). Historically, BSD has not allowed mknod(2) to be used
277 * to create fifos, but the Single UNIX Specification requires it.
278 */
279 for (i = 0; i < 2; i++) {
280 fifo_create_test(i);
281 fifo_permission_test(i);
282 }
233
283
234 fifo_permission_test();
235
236 return (0);
237}
284 return (0);
285}