1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * NAME 22 * write03.c 23 * 24 * DESCRIPTION 25 * Testcase to check that write(2) doesn't corrupt a file when it fails 26 * 27 * ALGORITHM 28 * Create a file for writing, write 100 bytes to it. Then make write(2) 29 * fail with some erroneous parameter, close the fd. Then reopen the 30 * file in RDONLY mode, and read the contents of the file. Compare the 31 * buffers, to see whether they are same. 32 * 33 * USAGE: <for command-line> 34 * write03 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 35 * where, -c n : Run n copies concurrently. 36 * -e : Turn on errno logging. 37 * -i n : Execute test n times. 38 * -I x : Execute test for x seconds. 39 * -P x : Pause for x seconds between iterations. 40 * -t : Turn on syscall timing. 41 * 42 * History 43 * 07/2001 John George 44 * -Ported 45 * 46 * Restrictions 47 * NONE 48 */ 49 50 #include <unistd.h> 51 #include <string.h> 52 #include <fcntl.h> 53 #include <errno.h> 54 #include "test.h" 55 #include <sys/mman.h> 56 57 char *TCID = "write03"; 58 int TST_TOTAL = 1; 59 60 char *bad_addr = 0; 61 62 void setup(void); 63 void cleanup(void); 64 65 char filename[100]; 66 67 #if !defined(UCLINUX) 68 69 int main(int argc, char **argv) 70 { 71 int lc; 72 73 char wbuf[BUFSIZ], rbuf[BUFSIZ]; 74 int fd; 75 76 tst_parse_opts(argc, argv, NULL, NULL); 77 78 /* global setup */ 79 setup(); 80 81 /* The following loop checks looping state if -i option given */ 82 for (lc = 0; TEST_LOOPING(lc); lc++) { 83 84 /* reset tst_count in case we are looping */ 85 tst_count = 0; 86 87 //block1: 88 tst_resm(TINFO, "Enter Block 1: test to check if write " 89 "corrupts the file when write fails"); 90 91 fd = creat(filename, 0644); 92 if (fd < 0) { 93 tst_resm(TBROK, "creating a new file failed"); 94 cleanup(); 95 } 96 97 (void)memset(wbuf, '0', 100); 98 99 if (write(fd, wbuf, 100) == -1) { 100 tst_resm(TFAIL, "failed to write to %s", filename); 101 cleanup(); 102 } 103 104 if (write(fd, bad_addr, 100) != -1) { 105 tst_resm(TFAIL, "write(2) failed to fail"); 106 cleanup(); 107 } 108 close(fd); 109 110 if ((fd = open(filename, O_RDONLY)) == -1) { 111 tst_resm(TBROK, "open(2) failed, errno: %d", errno); 112 cleanup(); 113 } 114 115 if (read(fd, rbuf, 100) == -1) { 116 tst_resm(TBROK, "read(2) failed, errno: %d", errno); 117 cleanup(); 118 } 119 120 if (memcmp(wbuf, rbuf, 100) == 0) { 121 tst_resm(TPASS, "failure of write(2) didnot corrupt " 122 "the file"); 123 } else { 124 tst_resm(TFAIL, "failure of write(2) corrupted the " 125 "file"); 126 } 127 tst_resm(TINFO, "Exit block 1"); 128 close(fd); 129 } 130 cleanup(); 131 tst_exit(); 132 } 133 134 #else 135 136 int main(void) 137 { 138 tst_resm(TINFO, "test is not available on uClinux"); 139 tst_exit(); 140 } 141 142 #endif /* if !defined(UCLINUX) */ 143 144 /* 145 * setup() - performs all ONE TIME setup for this test 146 */ 147 void setup(void) 148 { 149 150 tst_sig(FORK, DEF_HANDLER, cleanup); 151 152 /* Pause if that option was specified 153 * TEST_PAUSE contains the code to fork the test with the -i option. 154 * You want to make sure you do this before you create your temporary 155 * directory. 156 */ 157 TEST_PAUSE; 158 159 /* Create a unique temporary directory and chdir() to it. */ 160 tst_tmpdir(); 161 162 sprintf(filename, "./write03.%d", getpid()); 163 164 bad_addr = mmap(0, 1, PROT_NONE, 165 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0); 166 if (bad_addr == MAP_FAILED) { 167 printf("mmap failed\n"); 168 } 169 170 } 171 172 /* 173 * cleanup() - performs all ONE TIME cleanup for this test at 174 * completion or premature exit 175 */ 176 void cleanup(void) 177 { 178 179 unlink(filename); 180 tst_rmdir(); 181 182 } 183