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 * Test Name: truncate02 22 * 23 * Test Description: 24 * Verify that, truncate(2) succeeds to truncate a file to a certain length, 25 * but the attempt to read past the truncated length will fail.$ 26 * 27 * Expected Result: 28 * truncate(2) should return a value 0 and the attempt to read past the 29 * truncated length will fail. In case where the file before truncation was 30 * shorter, the bytes between the old and new should be all zeroes. 31 * 32 * Algorithm: 33 * Setup: 34 * Setup signal handling. 35 * Create temporary directory. 36 * Pause for SIGUSR1 if option specified. 37 * 38 * Test: 39 * Loop if the proper options are given. 40 * Execute system call 41 * Check return code, if system call failed (return=-1) 42 * Log the errno and Issue a FAIL message. 43 * Otherwise, 44 * Verify the Functionality of system call 45 * if successful, 46 * Issue Functionality-Pass message. 47 * Otherwise, 48 * Issue Functionality-Fail message. 49 * Cleanup: 50 * Print errno log and/or timing stats if options given 51 * Delete the temporary directory created. 52 * 53 * Usage: <for command-line> 54 * truncate02 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t] 55 * where, -c n : Run n copies concurrently. 56 * -e : Turn on errno logging. 57 * -f : Turn off functionality Testing. 58 * -i n : Execute test n times. 59 * -I x : Execute test for x seconds. 60 * -P x : Pause for x seconds between iterations. 61 * -t : Turn on syscall timing. 62 * 63 * History 64 * 07/2001 John George 65 * -Ported 66 * 67 * Restrictions: 68 * This test should be run by 'non-super-user' only. 69 * 70 */ 71 72 #include <sys/types.h> 73 #include <sys/stat.h> 74 #include <sys/fcntl.h> 75 #include <errno.h> 76 #include <string.h> 77 #include <signal.h> 78 79 #include "test.h" 80 81 #define TESTFILE "testfile" /* file under test */ 82 #define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH 83 #define BUF_SIZE 256 /* buffer size */ 84 #define FILE_SIZE 1024 /* test file size */ 85 #define TRUNC_LEN1 256 /* truncation length */ 86 #define TRUNC_LEN2 512 /* truncation length */ 87 88 TCID_DEFINE(truncate02); 89 int TST_TOTAL = 1; /* Total number of test conditions */ 90 int fd; /* file descriptor of testfile */ 91 char tst_buff[BUF_SIZE]; /* buffer to hold testfile contents */ 92 93 void setup(); /* setup function for the test */ 94 void cleanup(); /* cleanup function for the test */ 95 96 int main(int ac, char **av) 97 { 98 struct stat stat_buf; /* stat(2) struct contents */ 99 int lc, i; 100 off_t file_length2; /* test file length */ 101 off_t file_length1; /* test file length */ 102 int rbytes; /* bytes read from testfile */ 103 int read_len = 0; /* total no. of bytes read from testfile */ 104 int err_flag = 0; /* error indicator flag */ 105 106 tst_parse_opts(ac, av, NULL, NULL); 107 108 setup(); 109 110 for (lc = 0; TEST_LOOPING(lc); lc++) { 111 112 tst_count = 0; 113 114 /* 115 * Call truncate(2) to truncate a test file to a 116 * specified length (TRUNC_LEN1). 117 */ 118 TEST(truncate(TESTFILE, TRUNC_LEN1)); 119 120 if (TEST_RETURN == -1) { 121 tst_resm(TFAIL, 122 "truncate(%s, %d) Failed, errno=%d : %s", 123 TESTFILE, TRUNC_LEN1, TEST_ERRNO, 124 strerror(TEST_ERRNO)); 125 } else { 126 /* 127 * Get the testfile information using 128 * stat(2). 129 */ 130 if (stat(TESTFILE, &stat_buf) < 0) { 131 tst_brkm(TFAIL, cleanup, "stat(2) of " 132 "%s failed after 1st truncate, " 133 "error:%d", TESTFILE, errno); 134 } 135 file_length1 = stat_buf.st_size; 136 137 /* 138 * Set the file pointer of testfile to the 139 * beginning of the file. 140 */ 141 if (lseek(fd, 0, SEEK_SET) < 0) { 142 tst_brkm(TFAIL, cleanup, "lseek(2) on " 143 "%s failed after 1st truncate, " 144 "error:%d", TESTFILE, errno); 145 } 146 147 /* Read the testfile from the beginning. */ 148 while ((rbytes = read(fd, tst_buff, 149 sizeof(tst_buff))) > 0) { 150 read_len += rbytes; 151 } 152 153 /* 154 * Execute truncate(2) again to truncate 155 * testfile to a size TRUNC_LEN2. 156 */ 157 TEST(truncate(TESTFILE, TRUNC_LEN2)); 158 159 if (TEST_RETURN == -1) { 160 tst_resm(TFAIL, "truncate of %s to " 161 "size %d Failed, errno=%d : %s", 162 TESTFILE, TRUNC_LEN2, 163 TEST_ERRNO, 164 strerror(TEST_ERRNO)); 165 } 166 167 /* 168 * Get the testfile information using 169 * stat(2) 170 */ 171 if (stat(TESTFILE, &stat_buf) < 0) { 172 tst_brkm(TFAIL, cleanup, "stat(2) of " 173 "%s failed after 2nd truncate, " 174 "error:%d", TESTFILE, errno); 175 } 176 file_length2 = stat_buf.st_size; 177 178 /* 179 * Set the file pointer of testfile to the 180 * offset TRUNC_LEN1 of testfile. 181 */ 182 if (lseek(fd, TRUNC_LEN1, SEEK_SET) < 0) { 183 tst_brkm(TFAIL, cleanup, "lseek(2) on " 184 "%s failed after 2nd truncate, " 185 "error:%d", TESTFILE, errno); 186 } 187 188 /* Read the testfile contents till EOF */ 189 while ((rbytes = read(fd, tst_buff, 190 sizeof(tst_buff))) > 0) { 191 for (i = 0; i < rbytes; i++) { 192 if (tst_buff[i] != 0) { 193 err_flag++; 194 } 195 } 196 } 197 198 /* 199 * Check for expected size of testfile after 200 * issuing truncate(2) on it. 201 */ 202 if ((file_length1 != TRUNC_LEN1) || 203 (file_length2 != TRUNC_LEN2) || 204 (read_len != TRUNC_LEN1) || 205 (err_flag != 0)) { 206 tst_resm(TFAIL, "Functionality of " 207 "truncate(2) on %s Failed", 208 TESTFILE); 209 } else { 210 tst_resm(TPASS, 211 "Functionality of truncate(2) " 212 "on %s successful", TESTFILE); 213 } 214 } 215 tst_count++; /* incr. TEST_LOOP counter */ 216 } 217 218 cleanup(); 219 tst_exit(); 220 } 221 222 /* 223 * void 224 * setup() - performs all ONE TIME setup for this test. 225 * Create a temporary directory and change directory to it. 226 * Create a test file under temporary directory and write some 227 * data into it. 228 */ 229 void setup(void) 230 { 231 int i; 232 int wbytes; /* bytes written to testfile */ 233 int write_len = 0; /* total no. of bytes written to testfile */ 234 235 tst_sig(FORK, DEF_HANDLER, cleanup); 236 237 /* Pause if that option was specified 238 * TEST_PAUSE contains the code to fork the test with the -i option. 239 * You want to make sure you do this before you create your temporary 240 * directory. 241 */ 242 TEST_PAUSE; 243 244 tst_tmpdir(); 245 246 /* Fill the test buffer with the known data */ 247 for (i = 0; i < BUF_SIZE; i++) { 248 tst_buff[i] = 'a'; 249 } 250 251 /* Creat a testfile and write some data into it */ 252 if ((fd = open(TESTFILE, O_RDWR | O_CREAT, FILE_MODE)) == -1) { 253 tst_brkm(TBROK, cleanup, 254 "open(%s, O_RDWR|O_CREAT, %o) Failed, errno=%d : %s", 255 TESTFILE, FILE_MODE, errno, strerror(errno)); 256 } 257 258 /* Write to the file 1k data from the buffer */ 259 while (write_len < FILE_SIZE) { 260 if ((wbytes = write(fd, tst_buff, sizeof(tst_buff))) <= 0) { 261 tst_brkm(TBROK, cleanup, 262 "write(2) on %s Failed, errno=%d : %s", 263 TESTFILE, errno, strerror(errno)); 264 } else { 265 write_len += wbytes; 266 } 267 } 268 } 269 270 /* 271 * void 272 * cleanup() - performs all ONE TIME cleanup for this test at 273 * completion or premature exit. 274 * Close the temporary file opened for reading/writing. 275 * Remove the test directory and testfile created in the setup. 276 */ 277 void cleanup(void) 278 { 279 280 /* Close the testfile after writing data into it */ 281 if (close(fd) == -1) { 282 tst_brkm(TFAIL, NULL, 283 "close(%s) Failed, errno=%d : %s", 284 TESTFILE, errno, strerror(errno)); 285 } 286 287 tst_rmdir(); 288 289 } 290