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