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 off argument is constrained to be aligned and sized
8 * according to the value returned by
9 * sysconf( ) when passed _SC_PAGESIZE or _SC_PAGE_SIZE.
10 *
11 * The mmap( ) function shall fail if:
12 * [EINVAL] The addr argument (if MAP_FIXED was specified) or off is not a multiple of
13 * the page size as returned by sysconf( ), or is considered invalid by the
14 * implementation.
15 *
16 * Test step:
17 * 1. Set 'off' a value which is not a multiple of page size;
18 * 2. Call mmap() and get EINVAL;
19 *
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/11-1.c"
38
39int main()
40{
41  char tmpfname[256];
42  long  page_size;
43  long total_size;
44
45  void *pa = NULL;
46  void *addr = NULL;
47  size_t size;
48  int flag;
49  int fd;
50  off_t off = 0;
51  int prot;
52
53  page_size = sysconf(_SC_PAGE_SIZE);
54  total_size = 3 * page_size;
55  size = page_size;
56
57  snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_11_1_%ld",
58           (long)getpid());
59  unlink(tmpfname);
60  fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL,
61            S_IRUSR | S_IWUSR);
62  if (fd == -1)
63  {
64    printf(TNAME " Error at open(): %s\n",
65           strerror(errno));
66    exit(PTS_UNRESOLVED);
67  }
68  unlink(tmpfname);
69
70  if (ftruncate(fd, total_size) == -1)
71  {
72    printf(TNAME "Error at ftruncate(): %s\n",
73            strerror(errno));
74    exit(PTS_UNRESOLVED);
75  }
76
77  prot = PROT_READ | PROT_WRITE;
78  flag = MAP_SHARED;
79
80  /* This offset is considered illegal, not a multiple of page_size,
81   * unless the page_size is 1 byte, which is considered impossible.
82   */
83
84  off = page_size + 1;
85  pa = mmap(addr, size, prot, flag, fd, off);
86  if (pa == MAP_FAILED && errno == EINVAL)
87  {
88    printf("Test Pass: " TNAME " Get "
89    	     "EINVAL when 'off' is not a multiple of page size\n");
90    exit(PTS_PASS);
91  }
92
93  printf ("Test FAIL, Did not get EINVAL"
94          " when 'off' is not a multiple of page size, get: %s\n", strerror(errno));
95  close (fd);
96  munmap (pa, size);
97  return PTS_FAIL;
98}
99