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 mmap( ) function shall add an extra reference to the file
8 * associated with the file descriptor fildes which is not removed
9 * by a subsequent close( ) on that file descriptor.
10 * This reference shall be removed when there are no more
11 * mappings to the file.
12 *
13 * Test Steps:
14 * 1. Create a file, while it is open call unlink().
15 * 2. mmap the file to memory, then call close(). If mmap() add
16 *    extra reference to the file, the file descriptor will not be removed.
17 * 3. Try to open the file, open should success;
18 * 3. munmap the mapped memory;
19 * 4. Try open the file again, should get ENOENT;
20 */
21
22#define _XOPEN_SOURCE 600
23
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 <sys/wait.h>
32#include <fcntl.h>
33#include <string.h>
34#include <errno.h>
35#include "posixtest.h"
36
37#define TNAME "mmap/12-1.c"
38
39int main()
40{
41  char tmpfname[256];
42  long total_size;
43
44  void *pa = NULL;
45  void *addr = NULL;
46  size_t size;
47  int flag;
48  int fd, fd2;
49  off_t off = 0;
50  int prot;
51
52  total_size = 1024;
53  size = total_size;
54
55  snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_12_1_%ld",
56           (long)getpid());
57  unlink(tmpfname);
58  fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL,
59            S_IRUSR | S_IWUSR);
60  if (fd == -1)
61  {
62    printf(TNAME " Error at open(): %s\n",
63           strerror(errno));
64    exit(PTS_UNRESOLVED);
65  }
66
67  /* If there is no reference to the file,
68   * this file will be removed
69   */
70  unlink(tmpfname);
71
72  if (ftruncate(fd, total_size) == -1)
73  {
74    printf(TNAME "Error at ftruncate(): %s\n",
75            strerror(errno));
76    exit(PTS_UNRESOLVED);
77  }
78
79  flag = MAP_SHARED;
80  prot = PROT_READ | PROT_WRITE;
81
82  pa = mmap(addr, size, prot, flag, fd, off);
83  if (pa == MAP_FAILED)
84  {
85  	printf ("Test Fail: " TNAME " Error at mmap: %s\n",
86            strerror(errno));
87    exit(PTS_FAIL);
88  }
89
90  close(fd);
91
92  /* File still exists */
93
94  fd2 = open(tmpfname, O_RDWR, S_IRUSR | S_IWUSR);
95  if (fd == -1 && errno == ENOENT)
96  {
97    printf(TNAME " Error at open(): %s\n",
98           strerror(errno));
99    printf ("Test Fail: " TNAME  " The file is removed. mmap does not "
100    		    "add extra reference to the file associated with fd\n");
101    exit(PTS_FAIL);
102  }
103
104  munmap (pa, size);
105
106  /* The file should have been removed */
107  fd2 = open(tmpfname, O_RDWR, S_IRUSR | S_IWUSR);
108  if (fd2 == -1 && errno == ENOENT)
109  {
110    printf ("Test PASS: " TNAME  " The file is removed. munmap removed "
111    		    "reference to the file associated with fd\n");
112    exit(PTS_PASS);
113  }
114
115  if (fd2 != -1)
116  {
117  	printf ("Test FAIL: " TNAME
118            " The file is not removed. munmap does not remove "
119    	      "reference to the file associated with fd\n");
120  	return PTS_FAIL;
121  }
122
123  printf("PTS_UNRESLOVED " TNAME " Error at open(): %s\n",
124           strerror(errno));
125  return PTS_UNRESOLVED;
126}
127