1 /* 2 * Copyright (c) 2002, Intel Corporation. All rights reserved. 3 * Copyright (c) 2012, Cyril Hrubis <chrubis (at) suse.cz> 4 * 5 * This file is licensed under the GPL license. For the full content 6 * of this license, see the COPYING file at the top level of this 7 * source tree. 8 * 9 * The prot shall be either PROT_NONE or the bitwise-inclusive OR of 10 * one or more of the other flags in the following table, defined in the 11 * <sys/mman.h> header. 12 * PROT_READ Data can be read. 13 * PROT_WRITE Data can be written. 14 * PROT_EXEC Data can be executed. 15 * PROT_NONE Data cannot be accessed. 16 * If an implementation cannot support the combination of access types 17 * specified by prot, the call to mmap() shall fail. 18 * 19 * Test Steps: 20 * 1. call mmap() for all combinations permitted by POSIX 21 * 2. each should either succed or fail with ENOTSUP 22 */ 23 24 #define _XOPEN_SOURCE 600 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 struct testcase { 37 int prot; 38 int flags; 39 }; 40 41 struct testcase testcases[] = { 42 {.flags = MAP_SHARED,.prot = PROT_NONE}, 43 {.flags = MAP_SHARED,.prot = PROT_READ}, 44 {.flags = MAP_SHARED,.prot = PROT_WRITE}, 45 {.flags = MAP_SHARED,.prot = PROT_EXEC}, 46 {.flags = MAP_SHARED,.prot = PROT_READ | PROT_WRITE}, 47 {.flags = MAP_SHARED,.prot = PROT_READ | PROT_EXEC}, 48 {.flags = MAP_SHARED,.prot = PROT_EXEC | PROT_WRITE}, 49 {.flags = MAP_SHARED,.prot = PROT_READ | PROT_WRITE | PROT_EXEC}, 50 51 {.flags = MAP_PRIVATE,.prot = PROT_NONE}, 52 {.flags = MAP_PRIVATE,.prot = PROT_READ}, 53 {.flags = MAP_PRIVATE,.prot = PROT_WRITE}, 54 {.flags = MAP_PRIVATE,.prot = PROT_EXEC}, 55 {.flags = MAP_PRIVATE,.prot = PROT_READ | PROT_WRITE}, 56 {.flags = MAP_PRIVATE,.prot = PROT_READ | PROT_EXEC}, 57 {.flags = MAP_PRIVATE,.prot = PROT_EXEC | PROT_WRITE}, 58 {.flags = MAP_PRIVATE,.prot = PROT_READ | PROT_WRITE | PROT_EXEC}, 59 }; 60 61 static void print_error(struct testcase *t, int saved_errno) 62 { 63 printf("Combination of "); 64 65 if (t->prot == PROT_NONE) 66 printf("PROT_NONE "); 67 68 if (t->prot & PROT_READ) 69 printf("PROT_READ "); 70 71 if (t->prot & PROT_WRITE) 72 printf("PROT_WRITE "); 73 74 if (t->prot & PROT_EXEC) 75 printf("PROT_EXEC "); 76 77 switch (t->flags) { 78 case MAP_SHARED: 79 printf("with MAP_SHARED"); 80 break; 81 case MAP_PRIVATE: 82 printf("with MAP_PRIVATE"); 83 break; 84 } 85 86 printf(" has failed: %s\n", strerror(saved_errno)); 87 } 88 89 int main(void) 90 { 91 char tmpfname[256]; 92 void *pa; 93 size_t size = 1024; 94 int fd, fail = 0; 95 unsigned int i; 96 97 snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_5_1_%d", getpid()); 98 unlink(tmpfname); 99 fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); 100 if (fd == -1) { 101 printf("Error at open(): %s\n", strerror(errno)); 102 return PTS_UNRESOLVED; 103 } 104 unlink(tmpfname); 105 if (ftruncate(fd, size) == -1) { 106 printf("Error at ftruncate(): %s\n", strerror(errno)); 107 return PTS_UNRESOLVED; 108 } 109 110 for (i = 0; i < sizeof(testcases) / sizeof(*testcases); i++) { 111 112 pa = mmap(NULL, size, testcases[i].prot, testcases[i].flags, fd, 113 0); 114 115 if (pa == MAP_FAILED) { 116 if (errno != ENOTSUP) { 117 print_error(&testcases[i], errno); 118 fail++; 119 } 120 } else { 121 munmap(pa, size); 122 } 123 } 124 125 close(fd); 126 127 if (fail) 128 return PTS_FAIL; 129 130 printf("Test PASSED\n"); 131 return PTS_PASS; 132 } 133