1 /* 2 * Copyright (c) International Business Machines Corp., 2003 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 /* 20 * Test Description: 21 * Verify that truncating a mmaped file works correctly. 22 * 23 * Expected Result: 24 * ftruncate should be allowed to increase, decrease, or zero the 25 * size of a file that has been mmaped 26 * 27 * Test: 28 * Use ftruncate to shrink the file while it is mapped 29 * Use ftruncate to grow the file while it is mapped 30 * Use ftruncate to zero the size of the file while it is mapped 31 * 32 * HISTORY 33 * 04/2003 Written by Paul Larson 34 */ 35 #include <stdio.h> 36 #include <unistd.h> 37 #include <fcntl.h> 38 #include <errno.h> 39 #include <sys/mman.h> 40 #include <sys/types.h> 41 #include "test.h" 42 43 #define mapsize (1 << 14) 44 45 char *TCID = "mmap09"; 46 int TST_TOTAL = 3; 47 48 static int fd; 49 static char *maddr; 50 51 static struct test_case_t { 52 off_t newsize; 53 char *desc; 54 } TC[] = { 55 {mapsize - 8192, "ftruncate mmaped file to a smaller size"}, 56 {mapsize + 1024, "ftruncate mmaped file to a larger size"}, 57 {0, "ftruncate mmaped file to 0 size"}, 58 }; 59 60 static void setup(void); 61 static void cleanup(void); 62 63 int main(int argc, char **argv) 64 { 65 int lc; 66 int i; 67 68 tst_parse_opts(argc, argv, NULL, NULL); 69 70 setup(); 71 72 for (lc = 0; TEST_LOOPING(lc); lc++) { 73 tst_count = 0; 74 for (i = 0; i < TST_TOTAL; i++) { 75 TEST(ftruncate(fd, TC[i].newsize)); 76 77 if (TEST_RETURN == -1) { 78 tst_resm(TFAIL | TTERRNO, "%s", TC[i].desc); 79 } else { 80 tst_resm(TPASS, "%s", TC[i].desc); 81 } 82 } 83 84 } 85 86 cleanup(); 87 tst_exit(); 88 } 89 90 static void setup(void) 91 { 92 tst_sig(NOFORK, DEF_HANDLER, cleanup); 93 94 TEST_PAUSE; 95 96 tst_tmpdir(); 97 98 if ((fd = open("mmaptest", O_RDWR | O_CREAT, 0666)) < 0) 99 tst_brkm(TFAIL | TERRNO, cleanup, "opening mmaptest failed"); 100 101 /* ftruncate the file to 16k */ 102 if (ftruncate(fd, mapsize) < 0) 103 tst_brkm(TFAIL | TERRNO, cleanup, "ftruncate file failed"); 104 105 maddr = mmap(0, mapsize, PROT_READ | PROT_WRITE, 106 MAP_FILE | MAP_SHARED, fd, 0); 107 if (maddr == MAP_FAILED) 108 tst_brkm(TFAIL | TERRNO, cleanup, "mmapping mmaptest failed"); 109 110 /* fill up the file with A's */ 111 memset(maddr, 'A', mapsize); 112 } 113 114 static void cleanup(void) 115 { 116 munmap(maddr, mapsize); 117 close(fd); 118 tst_rmdir(); 119 } 120