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