1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 5f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 6f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 7f08c3bdfSopenharmony_ci * (at your option) any later version. 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 10f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 13f08c3bdfSopenharmony_ci * 14f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 15f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 16f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17f08c3bdfSopenharmony_ci */ 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci/* 20f08c3bdfSopenharmony_ci * Test Description: 21f08c3bdfSopenharmony_ci * Call mmap() to map a file creating a mapped region with read/exec access 22f08c3bdfSopenharmony_ci * under the following conditions - 23f08c3bdfSopenharmony_ci * - The prot parameter is set to PROT_READ|PROT_EXEC 24f08c3bdfSopenharmony_ci * - The file descriptor is open for read 25f08c3bdfSopenharmony_ci * - The file being mapped has read and execute permission bit set. 26f08c3bdfSopenharmony_ci * - The minimum file permissions should be 0555. 27f08c3bdfSopenharmony_ci * 28f08c3bdfSopenharmony_ci * The call should succeed to map the file creating mapped memory with the 29f08c3bdfSopenharmony_ci * required attributes. 30f08c3bdfSopenharmony_ci * 31f08c3bdfSopenharmony_ci * Expected Result: 32f08c3bdfSopenharmony_ci * mmap() should succeed returning the address of the mapped region, 33f08c3bdfSopenharmony_ci * and the mapped region should contain the contents of the mapped file. 34f08c3bdfSopenharmony_ci * 35f08c3bdfSopenharmony_ci * HISTORY 36f08c3bdfSopenharmony_ci * 07/2001 Ported by Wayne Boyer 37f08c3bdfSopenharmony_ci */ 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_ci#include <stdio.h> 40f08c3bdfSopenharmony_ci#include <stdlib.h> 41f08c3bdfSopenharmony_ci#include <sys/types.h> 42f08c3bdfSopenharmony_ci#include <errno.h> 43f08c3bdfSopenharmony_ci#include <unistd.h> 44f08c3bdfSopenharmony_ci#include <fcntl.h> 45f08c3bdfSopenharmony_ci#include <string.h> 46f08c3bdfSopenharmony_ci#include <signal.h> 47f08c3bdfSopenharmony_ci#include <sys/stat.h> 48f08c3bdfSopenharmony_ci#include <sys/mman.h> 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci#include "test.h" 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci#define TEMPFILE "mmapfile" 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_cichar *TCID = "mmap04"; 55f08c3bdfSopenharmony_ciint TST_TOTAL = 1; 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_cistatic size_t page_sz; 58f08c3bdfSopenharmony_cistatic char *addr; 59f08c3bdfSopenharmony_cistatic char *dummy; 60f08c3bdfSopenharmony_cistatic int fildes; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic void setup(void); 63f08c3bdfSopenharmony_cistatic void cleanup(void); 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_ciint main(int ac, char **av) 66f08c3bdfSopenharmony_ci{ 67f08c3bdfSopenharmony_ci int lc; 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci tst_parse_opts(ac, av, NULL, NULL); 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci setup(); 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); lc++) { 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci tst_count = 0; 76f08c3bdfSopenharmony_ci 77f08c3bdfSopenharmony_ci /* 78f08c3bdfSopenharmony_ci * Call mmap to map the temporary file 'TEMPFILE' 79f08c3bdfSopenharmony_ci * with read and execute access. 80f08c3bdfSopenharmony_ci */ 81f08c3bdfSopenharmony_ci errno = 0; 82f08c3bdfSopenharmony_ci addr = mmap(0, page_sz, PROT_READ | PROT_EXEC, 83f08c3bdfSopenharmony_ci MAP_FILE | MAP_SHARED, fildes, 0); 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci /* Check for the return value of mmap() */ 86f08c3bdfSopenharmony_ci if (addr == MAP_FAILED) { 87f08c3bdfSopenharmony_ci tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE); 88f08c3bdfSopenharmony_ci continue; 89f08c3bdfSopenharmony_ci } 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci /* 92f08c3bdfSopenharmony_ci * Read the file contents into the dummy 93f08c3bdfSopenharmony_ci * variable. 94f08c3bdfSopenharmony_ci */ 95f08c3bdfSopenharmony_ci if (read(fildes, dummy, page_sz) < 0) { 96f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "reading %s failed", 97f08c3bdfSopenharmony_ci TEMPFILE); 98f08c3bdfSopenharmony_ci } 99f08c3bdfSopenharmony_ci 100f08c3bdfSopenharmony_ci /* 101f08c3bdfSopenharmony_ci * Check whether the mapped memory region 102f08c3bdfSopenharmony_ci * has the file contents. 103f08c3bdfSopenharmony_ci */ 104f08c3bdfSopenharmony_ci if (memcmp(dummy, addr, page_sz)) { 105f08c3bdfSopenharmony_ci tst_resm(TFAIL, 106f08c3bdfSopenharmony_ci "mapped memory region contains invalid " 107f08c3bdfSopenharmony_ci "data"); 108f08c3bdfSopenharmony_ci } else { 109f08c3bdfSopenharmony_ci tst_resm(TPASS, 110f08c3bdfSopenharmony_ci "Functionality of mmap() successful"); 111f08c3bdfSopenharmony_ci } 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ci /* Clean up things in case we are looping. */ 114f08c3bdfSopenharmony_ci /* Unmap the mapped memory */ 115f08c3bdfSopenharmony_ci if (munmap(addr, page_sz) != 0) { 116f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "munmapping failed"); 117f08c3bdfSopenharmony_ci } 118f08c3bdfSopenharmony_ci } 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci cleanup(); 121f08c3bdfSopenharmony_ci tst_exit(); 122f08c3bdfSopenharmony_ci} 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_cistatic void setup(void) 125f08c3bdfSopenharmony_ci{ 126f08c3bdfSopenharmony_ci char *tst_buff; 127f08c3bdfSopenharmony_ci 128f08c3bdfSopenharmony_ci tst_sig(NOFORK, DEF_HANDLER, cleanup); 129f08c3bdfSopenharmony_ci 130f08c3bdfSopenharmony_ci TEST_PAUSE; 131f08c3bdfSopenharmony_ci 132f08c3bdfSopenharmony_ci page_sz = getpagesize(); 133f08c3bdfSopenharmony_ci 134f08c3bdfSopenharmony_ci if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) { 135f08c3bdfSopenharmony_ci tst_brkm(TFAIL, NULL, "calloc failed (tst_buff)"); 136f08c3bdfSopenharmony_ci } 137f08c3bdfSopenharmony_ci 138f08c3bdfSopenharmony_ci /* Fill the test buffer with the known data */ 139f08c3bdfSopenharmony_ci memset(tst_buff, 'A', page_sz); 140f08c3bdfSopenharmony_ci 141f08c3bdfSopenharmony_ci tst_tmpdir(); 142f08c3bdfSopenharmony_ci 143f08c3bdfSopenharmony_ci /* Creat a temporary file used for mapping */ 144f08c3bdfSopenharmony_ci if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) { 145f08c3bdfSopenharmony_ci free(tst_buff); 146f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE); 147f08c3bdfSopenharmony_ci } 148f08c3bdfSopenharmony_ci 149f08c3bdfSopenharmony_ci /* Write test buffer contents into temporary file */ 150f08c3bdfSopenharmony_ci if (write(fildes, tst_buff, page_sz) < (ssize_t)page_sz) { 151f08c3bdfSopenharmony_ci free(tst_buff); 152f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE); 153f08c3bdfSopenharmony_ci } 154f08c3bdfSopenharmony_ci 155f08c3bdfSopenharmony_ci /* Free the memory allocated for test buffer */ 156f08c3bdfSopenharmony_ci free(tst_buff); 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_ci /* Make sure proper permissions set on file */ 159f08c3bdfSopenharmony_ci if (fchmod(fildes, 0555) < 0) { 160f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "fchmod of %s failed", TEMPFILE); 161f08c3bdfSopenharmony_ci } 162f08c3bdfSopenharmony_ci 163f08c3bdfSopenharmony_ci /* Close the temporary file opened for write */ 164f08c3bdfSopenharmony_ci if (close(fildes) < 0) { 165f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "closing %s failed", TEMPFILE); 166f08c3bdfSopenharmony_ci } 167f08c3bdfSopenharmony_ci 168f08c3bdfSopenharmony_ci /* Allocate and initialize dummy string of system page size bytes */ 169f08c3bdfSopenharmony_ci if ((dummy = calloc(page_sz, sizeof(char))) == NULL) { 170f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "calloc failed (dummy)"); 171f08c3bdfSopenharmony_ci } 172f08c3bdfSopenharmony_ci 173f08c3bdfSopenharmony_ci /* Open the temporary file again for reading */ 174f08c3bdfSopenharmony_ci if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) { 175f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, 176f08c3bdfSopenharmony_ci "opening %s read-only failed", TEMPFILE); 177f08c3bdfSopenharmony_ci } 178f08c3bdfSopenharmony_ci} 179f08c3bdfSopenharmony_ci 180f08c3bdfSopenharmony_cistatic void cleanup(void) 181f08c3bdfSopenharmony_ci{ 182f08c3bdfSopenharmony_ci close(fildes); 183f08c3bdfSopenharmony_ci free(dummy); 184f08c3bdfSopenharmony_ci tst_rmdir(); 185f08c3bdfSopenharmony_ci} 186