1 /* 2 * Copyright (c) International Business Machines Corp., 2001 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 * Call mmap() with prot parameter set to PROT_READ and with the file 22 * descriptor being open for read, to map a file creating mapped memory 23 * with read access. The minimum file permissions should be 0444. 24 * 25 * The call should succeed to create the mapped region with required 26 * attributes. 27 * 28 * Expected Result: 29 * mmap() should succeed returning the address of the mapped region, 30 * the mapped region should contain the contents of the mapped file. 31 * 32 * HISTORY 33 * 07/2001 Ported by Wayne Boyer 34 */ 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <sys/types.h> 38 #include <errno.h> 39 #include <unistd.h> 40 #include <fcntl.h> 41 #include <string.h> 42 #include <signal.h> 43 #include <sys/stat.h> 44 #include <sys/mman.h> 45 46 #include "test.h" 47 48 #define TEMPFILE "mmapfile" 49 50 char *TCID = "mmap02"; 51 int TST_TOTAL = 1; 52 53 static char *addr; 54 static char *dummy; 55 static size_t page_sz; 56 static int fildes; 57 58 static void setup(void); 59 static void cleanup(void); 60 61 int main(int ac, char **av) 62 { 63 int lc; 64 65 tst_parse_opts(ac, av, NULL, NULL); 66 67 setup(); 68 69 for (lc = 0; TEST_LOOPING(lc); lc++) { 70 71 tst_count = 0; 72 73 /* 74 * Call mmap to map the temporary file 'TEMPFILE' 75 * with read access. 76 */ 77 errno = 0; 78 addr = mmap(0, page_sz, PROT_READ, 79 MAP_FILE | MAP_SHARED, fildes, 0); 80 81 /* Check for the return value of mmap() */ 82 if (addr == MAP_FAILED) { 83 tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE); 84 continue; 85 } 86 87 /* 88 * Read the file contents into the dummy 89 * string. 90 */ 91 if (read(fildes, dummy, page_sz) < 0) { 92 tst_brkm(TFAIL | TERRNO, cleanup, 93 "reading %s failed", TEMPFILE); 94 } 95 96 /* 97 * Check whether mapped memory region has 98 * the file contents. 99 */ 100 if (memcmp(dummy, addr, page_sz)) { 101 tst_resm(TFAIL, "mapped memory area contains " 102 "invalid data"); 103 } else { 104 tst_resm(TPASS, 105 "Functionality of mmap() successful"); 106 } 107 108 /* Clean up things in case we are looping */ 109 /* Unmap the mapped memory */ 110 if (munmap(addr, page_sz) != 0) { 111 tst_brkm(TFAIL | TERRNO, cleanup, "munmapping failed"); 112 } 113 } 114 115 cleanup(); 116 tst_exit(); 117 } 118 119 static void setup(void) 120 { 121 char *tst_buff; 122 123 tst_sig(FORK, DEF_HANDLER, cleanup); 124 125 TEST_PAUSE; 126 127 page_sz = getpagesize(); 128 129 /* Allocate space for the test buffer */ 130 if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) { 131 tst_brkm(TFAIL, NULL, "calloc failed (tst_buff)"); 132 } 133 134 /* Fill the test buffer with the known data */ 135 memset(tst_buff, 'A', page_sz); 136 137 tst_tmpdir(); 138 139 /* Creat a temporary file used for mapping */ 140 if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) { 141 free(tst_buff); 142 tst_brkm(TFAIL | TERRNO, cleanup, "opening %s failed", 143 TEMPFILE); 144 } 145 146 /* Write test buffer contents into temporary file */ 147 if (write(fildes, tst_buff, page_sz) < page_sz) { 148 free(tst_buff); 149 tst_brkm(TFAIL | TERRNO, cleanup, 150 "writing to %s failed", TEMPFILE); 151 } 152 153 /* Free the memory allocated for test buffer */ 154 free(tst_buff); 155 156 /* Change Mode permissions on Temporary file */ 157 if (fchmod(fildes, 0444) < 0) { 158 tst_brkm(TFAIL | TERRNO, cleanup, "fchmod(%s, 0444) failed", 159 TEMPFILE); 160 } 161 162 /* Close the temporary file */ 163 if (close(fildes) < 0) { 164 tst_brkm(TFAIL | TERRNO, cleanup, "closing %s failed", 165 TEMPFILE); 166 } 167 168 /* Open the temporary file again, - Readonly mode */ 169 if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) { 170 tst_brkm(TFAIL, cleanup, "reopening %s readonly failed", 171 TEMPFILE); 172 } 173 174 /* Allocate and initialize dummy string of system page size bytes */ 175 if ((dummy = calloc(page_sz, sizeof(char))) == NULL) { 176 tst_brkm(TFAIL, cleanup, "calloc failed (dummy)"); 177 } 178 179 } 180 181 static void cleanup(void) 182 { 183 close(fildes); 184 free(dummy); 185 tst_rmdir(); 186 } 187