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