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 *
8 * The mmap( ) function shall fail if:
9 * ML [EAGAIN] The mapping could not be locked in memory,
10 * if required by mlockall ( ), due toa lack of resources.
11 *
12 * Test Step:
13 * 1. Call mlockall(), setting MCL_FUTURE;
14 * 2. Call setrlimit(), set rlim_cur of resource RLIMIT_MEMLOCK to a
15 *    certain value.
16 * 3. Map a shared memory object, with size larger than the
17 *    rlim_cur value set in step 2
18 * 4. Should get EAGAIN.
19 */
20
21#define _XOPEN_SOURCE 600
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/resource.h>
30#include <fcntl.h>
31#include <string.h>
32#include <errno.h>
33#include "posixtest.h"
34
35#define TNAME "mmap/18-1.c"
36
37int main()
38{
39  char tmpfname[256];
40  int shm_fd;
41
42  /* size of shared memory object */
43  size_t shm_size;
44
45  void *pa = NULL;
46  void *addr = NULL;
47  size_t len;
48  int prot = PROT_READ | PROT_WRITE;
49  int flag = MAP_SHARED;
50  int fd;
51  off_t off = 0;
52
53  size_t memlock_size;
54  struct rlimit rlim = {.rlim_max = RLIM_INFINITY};
55
56  /* Lock all memory page to be mapped */
57  if (mlockall(MCL_FUTURE) == -1)
58  {
59    printf(TNAME " Error at mlockall(): %s\n", strerror(errno));
60		return PTS_UNRESOLVED;
61  }
62
63  /* Set rlim.rlim_cur < len */
64
65  len = 1024 * 1024;
66  memlock_size = len / 2;
67  rlim.rlim_cur = memlock_size;
68
69  /* We don't cate the size of the actual shared memory object */
70  shm_size = 1024;
71
72  if (setrlimit (RLIMIT_MEMLOCK, &rlim) == -1)
73  {
74		printf(TNAME " Error at setrlimit(): %s\n", strerror(errno));
75		return PTS_UNRESOLVED;
76  }
77
78  snprintf(tmpfname, sizeof(tmpfname), "pts_mmap_18_1_%ld",
79           (long)getpid());
80
81  /* Create shared object */
82	shm_unlink(tmpfname);
83	shm_fd = shm_open(tmpfname, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
84	if(shm_fd == -1)
85	{
86		printf(TNAME " Error at shm_open(): %s\n", strerror(errno));
87		return PTS_UNRESOLVED;
88	}
89  shm_unlink(tmpfname);
90  if(ftruncate(shm_fd, shm_size) == -1) {
91    printf(TNAME " Error at ftruncate(): %s\n", strerror(errno));
92    return PTS_UNRESOLVED;
93  }
94
95  fd = shm_fd;
96  pa = mmap (addr, len, prot, flag, fd, off);
97  if (pa == MAP_FAILED && errno == EAGAIN)
98  {
99    printf ("Test Pass: " TNAME " Get EAGAIN: %s\n",
100            strerror(errno));
101    close(fd);
102    munmap(pa, len);
103    exit(PTS_PASS);
104  }
105
106  if (pa == MAP_FAILED)
107    perror("Error at mmap()");
108  close(fd);
109  munmap(pa, len);
110  printf ("Test Fail: Did not get EAGAIN as expected\n");
111  return PTS_FAIL;
112}
113