Sync usage with man page.
[netbsd-mini2440.git] / dist / ntp / ElectricFence / page.c
blob9d1768af2e79c00f5481ea7b939912b901902b8c
1 /* $NetBSD$ */
3 #ifdef HAVE_CONFIG_H
4 # include <config.h>
5 #endif
6 #include "efence.h"
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <sys/mman.h>
11 #include <stdio.h>
12 #include <errno.h>
13 #include <string.h>
16 * Lots of systems are missing the definition of PROT_NONE.
18 #ifndef PROT_NONE
19 #define PROT_NONE 0
20 #endif
23 * 386 BSD has MAP_ANON instead of MAP_ANONYMOUS.
25 #if ( !defined(MAP_ANONYMOUS) && defined(MAP_ANON) )
26 #define MAP_ANONYMOUS MAP_ANON
27 #endif
30 * For some reason, I can't find mprotect() in any of the headers on
31 * IRIX or SunOS 4.1.2
33 /* extern C_LINKAGE int mprotect(void * addr, size_t len, int prot); */
35 static caddr_t startAddr = (caddr_t) 0;
37 static const char *
38 stringErrorReport(void)
40 return strerror(errno);
44 * Create memory.
46 #if defined(MAP_ANONYMOUS)
47 void *
48 Page_Create(size_t size)
50 caddr_t allocation;
53 * In this version, "startAddr" is a _hint_, not a demand.
54 * When the memory I map here is contiguous with other
55 * mappings, the allocator can coalesce the memory from two
56 * or more mappings into one large contiguous chunk, and thus
57 * might be able to find a fit that would not otherwise have
58 * been possible. I could _force_ it to be contiguous by using
59 * the MMAP_FIXED flag, but I don't want to stomp on memory mappings
60 * generated by other software, etc.
62 allocation = (caddr_t) mmap(
63 startAddr
64 ,(int)size
65 ,PROT_READ|PROT_WRITE
66 ,MAP_PRIVATE|MAP_ANONYMOUS
67 ,-1
68 ,0);
70 #ifndef __hpux
72 * Set the "address hint" for the next mmap() so that it will abut
73 * the mapping we just created.
75 * HP/UX 9.01 has a kernel bug that makes mmap() fail sometimes
76 * when given a non-zero address hint, so we'll leave the hint set
77 * to zero on that system. HP recently told me this is now fixed.
78 * Someone please tell me when it is probable to assume that most
79 * of those systems that were running 9.01 have been upgraded.
81 startAddr = allocation + size;
82 #endif
84 if ( allocation == (caddr_t)-1 )
85 EF_Exit("mmap() failed: %s", stringErrorReport());
87 return (void *)allocation;
89 #else
90 void *
91 Page_Create(size_t size)
93 static int devZeroFd = -1;
94 caddr_t allocation;
96 if ( devZeroFd == -1 ) {
97 devZeroFd = open("/dev/zero", O_RDWR);
98 if ( devZeroFd < 0 )
99 EF_Exit(
100 "open() on /dev/zero failed: %s"
101 ,stringErrorReport());
105 * In this version, "startAddr" is a _hint_, not a demand.
106 * When the memory I map here is contiguous with other
107 * mappings, the allocator can coalesce the memory from two
108 * or more mappings into one large contiguous chunk, and thus
109 * might be able to find a fit that would not otherwise have
110 * been possible. I could _force_ it to be contiguous by using
111 * the MMAP_FIXED flag, but I don't want to stomp on memory mappings
112 * generated by other software, etc.
114 allocation = (caddr_t) mmap(
115 startAddr
116 ,(int)size
117 ,PROT_READ|PROT_WRITE
118 ,MAP_PRIVATE
119 ,devZeroFd
120 ,0);
122 startAddr = allocation + size;
124 if ( allocation == (caddr_t)-1 )
125 EF_Exit("mmap() failed: %s", stringErrorReport());
127 return (void *)allocation;
129 #endif
131 static void
132 mprotectFailed(void)
134 EF_Exit("mprotect() failed: %s", stringErrorReport());
137 void
138 Page_AllowAccess(void * address, size_t size)
140 if ( mprotect((caddr_t)address, size, PROT_READ|PROT_WRITE) < 0 )
141 mprotectFailed();
144 void
145 Page_DenyAccess(void * address, size_t size)
147 if ( mprotect((caddr_t)address, size, PROT_NONE) < 0 )
148 mprotectFailed();
151 void
152 Page_Delete(void * address, size_t size)
154 if ( munmap((caddr_t)address, size) < 0 )
155 Page_DenyAccess(address, size);
158 #if defined(_SC_PAGESIZE)
159 size_t
160 Page_Size(void)
162 return (size_t)sysconf(_SC_PAGESIZE);
164 #elif defined(_SC_PAGE_SIZE)
165 size_t
166 Page_Size(void)
168 return (size_t)sysconf(_SC_PAGE_SIZE);
170 #else
171 /* extern int getpagesize(); */
172 size_t
173 Page_Size(void)
175 return getpagesize();
177 #endif