Home | History | Annotate | Download | only in mmap
      1 /*
      2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
      3  * Copyright (c) 2012, Cyril Hrubis <chrubis (at) suse.cz>
      4  *
      5  * This file is licensed under the GPL license.  For the full content
      6  * of this license, see the COPYING file at the top level of this
      7  * source tree.
      8  *
      9  * The mapping established by mmap() shall replace any previous
     10  * mappings for those whole pages containing any part of the address
     11  * space of the process starting at pa and continuing for len bytes.
     12  *
     13  * Test Steps:
     14  * 1. Set the size of the file to be mapped as (2 * _SC_PAGE_SIZE);
     15  * 2. Map size = (_SC_PAGE_SIZE + 2) bytes into memory,
     16  *    setting the content as 'a'. The mapped address is pa.
     17  * 2. Map size2 = (_SC_PAGE_SIZE + 1) bytes into memory, starting at the same
     18  *    address as the first mmap, i.e. pa, using MAP_FIXED flag.
     19  *    Setting the cotent as 'b'
     20  * 3. Test whether byte *(pa + size) is 'b'.
     21  */
     22 
     23 #define _XOPEN_SOURCE 600
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <unistd.h>
     27 #include <sys/mman.h>
     28 #include <sys/types.h>
     29 #include <sys/stat.h>
     30 #include <fcntl.h>
     31 #include <string.h>
     32 #include <errno.h>
     33 #include "posixtest.h"
     34 
     35 #ifdef MAP_FIXED
     36 int main(void)
     37 {
     38 	char tmpfname[256];
     39 	char tmpfname2[256];
     40 	char *data;
     41 	long total_size;
     42 	long page_size;
     43 
     44 	void *pa;
     45 	size_t size;
     46 	int fd;
     47 
     48 	void *pa2;
     49 	size_t size2;
     50 	int fd2;
     51 
     52 	char *ch;
     53 
     54 	page_size = sysconf(_SC_PAGE_SIZE);
     55 	size = page_size + 2;
     56 	size2 = page_size + 1;
     57 
     58 	/* Size of the file */
     59 	total_size = 2 * page_size;
     60 
     61 	snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_3_1_%d_1",
     62 		 getpid());
     63 	snprintf(tmpfname2, sizeof(tmpfname2), "/tmp/pts_mmap_3_1_%d_2",
     64 		 getpid());
     65 
     66 	unlink(tmpfname);
     67 	unlink(tmpfname2);
     68 
     69 	fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
     70 	fd2 = open(tmpfname2, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
     71 	if (fd == -1 || fd2 == -1) {
     72 		printf("Error at open(): %s\n", strerror(errno));
     73 		return PTS_UNRESOLVED;
     74 	}
     75 
     76 	unlink(tmpfname);
     77 	unlink(tmpfname2);
     78 
     79 	data = malloc(total_size);
     80 
     81 	memset(data, 'a', total_size);
     82 	if (write(fd, data, total_size) != total_size) {
     83 		printf("Error at write(), fd: %s\n", strerror(errno));
     84 		return PTS_UNRESOLVED;
     85 	}
     86 
     87 	memset(data, 'b', total_size);
     88 	if (write(fd2, data, total_size) != total_size) {
     89 		printf("Error at write(), fd1: %s\n", strerror(errno));
     90 		return PTS_UNRESOLVED;
     91 	}
     92 
     93 	free(data);
     94 
     95 	/* Map first file */
     96 	pa = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
     97 	if (pa == MAP_FAILED) {
     98 		printf("Error at mmap: %s\n", strerror(errno));
     99 		return PTS_FAIL;
    100 	}
    101 
    102 	ch = pa + size;
    103 	if (*ch != 'a') {
    104 		printf("Test Fail: The file is not mapped correctly\n");
    105 		return PTS_FAIL;
    106 	}
    107 
    108 	/* Replace orginal mapping */
    109 	pa2 =
    110 	    mmap(pa, size2, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd2,
    111 		 0);
    112 	if (pa2 == MAP_FAILED) {
    113 		printf("Error at 2nd mmap: %s\n", strerror(errno));
    114 		return PTS_FAIL;
    115 	}
    116 
    117 	if (pa2 != pa) {
    118 		printf("Error at mmap, the second mmap does not replaced the"
    119 		       " first mapping\n");
    120 		return PTS_FAIL;
    121 	}
    122 
    123 	ch = pa2 + size;
    124 	if (*ch != 'b') {
    125 		printf("The original mapped page has not been replaced\n");
    126 		return PTS_FAIL;
    127 	}
    128 
    129 	close(fd);
    130 	close(fd2);
    131 	munmap(pa, size);
    132 	munmap(pa2, size2);
    133 	printf("Test PASSED\n");
    134 	return PTS_PASS;
    135 }
    136 #else
    137 int main(void)
    138 {
    139 	printf("MAP_FIXED was not defined at the time of compilation\n");
    140 	return PTS_UNRESOLVED;
    141 }
    142 #endif /* MAP_FIXED */
    143