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 munmap( ) function shall remove any mappings for those
8 * entire pages containing any part of the address space of
9 * the process starting at addr and continuing for len bytes.
10 * Further references to these pages shall result in the
11 * generation of a SIGSEGV signal to the process.
12 *
13 * Test Step:
14 * 1. map a file into memory;
15 * 2. unmap;
16 * 3. Try to reference the unmapped memory, test whether SIGSEGV
17 *    is triggered.
18 */
19
20#define _XOPEN_SOURCE 600
21
22#include <pthread.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <unistd.h>
26#include <sys/mman.h>
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <sys/wait.h>
30#include <fcntl.h>
31#include <string.h>
32#include <errno.h>
33#include "posixtest.h"
34
35#define TNAME "munmap/1-2.c"
36
37void sigsegv_handler(int signum)
38{
39	printf ("Got SIGSEGV\n");
40	printf ("Test PASSED\n");
41  exit(PTS_PASS);
42}
43
44int main()
45{
46  char tmpfname[256];
47  long file_size;
48
49  void *pa = NULL;
50  void *addr = NULL;
51  size_t len;
52  int flag;
53  int fd;
54  off_t off = 0;
55  int prot;
56
57  int page_size;
58
59  char *ch;
60
61  struct sigaction sa;
62
63  sigfillset(&sa.sa_mask);
64  sa.sa_handler = sigsegv_handler;
65  sigaction(SIGSEGV, &sa, NULL);
66
67  page_size = sysconf(_SC_PAGE_SIZE);
68  file_size = 2 * page_size;
69
70  /* We hope to map 2 pages */
71  len = page_size + 1;
72
73  /* Create tmp file */
74  snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_munmap_1_1_%ld",
75           (long)getpid());
76  unlink(tmpfname);
77  fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL,
78            S_IRUSR | S_IWUSR);
79  if (fd == -1)
80  {
81    printf(TNAME " Error at open(): %s\n",
82           strerror(errno));
83    exit(PTS_UNRESOLVED);
84  }
85  unlink(tmpfname);
86
87  if (ftruncate (fd, file_size) == -1)
88  {
89    printf("Error at ftruncate: %s\n", strerror(errno));
90    exit(PTS_UNRESOLVED);
91  }
92
93  flag = MAP_SHARED;
94  prot = PROT_READ | PROT_WRITE;
95  pa = mmap(addr, len, prot, flag, fd, off);
96  if (pa == MAP_FAILED)
97  {
98  	printf ("Test UNRESOLVED: " TNAME " Error at mmap: %s\n",
99            strerror(errno));
100    exit(PTS_UNRESOLVED);
101  }
102
103  ch = pa;
104  *ch = 'b';
105
106  close (fd);
107  munmap (pa, len);
108
109  /* Should trigger SIGSEGV here */
110  *ch = 'a';
111
112  printf ("Test FAILED: Did not trigger SIGSEGV\n");
113  return PTS_FAIL;
114}
115