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