]>
Commit | Line | Data |
---|---|---|
1fd5e000 CF |
1 | /* shared.cc: shared data area support. |
2 | ||
ce006ffa | 3 | Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
1fd5e000 CF |
4 | |
5 | This file is part of Cygwin. | |
6 | ||
7 | This software is a copyrighted work licensed under the terms of the | |
8 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
9 | details. */ | |
10 | ||
4c8d72de | 11 | #include "winsup.h" |
1fd5e000 CF |
12 | #include <unistd.h> |
13 | #include <stdio.h> | |
14 | #include <stdlib.h> | |
15 | #include <grp.h> | |
16 | #include <pwd.h> | |
e2ebe117 | 17 | #include "pinfo.h" |
6b91b8d5 | 18 | #include "security.h" |
0381fec6 | 19 | #include "fhandler.h" |
47063f00 | 20 | #include "path.h" |
0381fec6 | 21 | #include "dtable.h" |
df63bd49 | 22 | #include "cygerrno.h" |
1f0f8e12 | 23 | #include "cygheap.h" |
6a4878cf | 24 | #include "heap.h" |
77f4a250 | 25 | #include "shared_info_magic.h" |
f0338f54 CF |
26 | #include "registry.h" |
27 | #include "cygwin_version.h" | |
fdb28b5e | 28 | #include "child_info.h" |
1fd5e000 | 29 | |
54030e21 CF |
30 | shared_info NO_COPY *cygwin_shared; |
31 | mount_info NO_COPY *mount_table; | |
e851d2fe | 32 | HANDLE NO_COPY cygwin_mount_h; |
1fd5e000 | 33 | |
1fd5e000 | 34 | char * __stdcall |
5c768c97 | 35 | shared_name (char *ret_buf, const char *str, int num) |
1fd5e000 | 36 | { |
9867ecfd | 37 | extern bool _cygwin_testing; |
1fd5e000 | 38 | |
5c768c97 | 39 | __small_sprintf (ret_buf, "%s%s.%s.%d", |
d4f3ce31 CV |
40 | wincap.has_terminal_services () ? "Global\\" : "", |
41 | cygwin_version.shared_id, str, num); | |
72005574 | 42 | if (_cygwin_testing) |
5c768c97 CV |
43 | strcat (ret_buf, cygwin_version.dll_build_date); |
44 | return ret_buf; | |
1fd5e000 CF |
45 | } |
46 | ||
fdb28b5e CF |
47 | #define page_const (65535) |
48 | #define pround(n) (((size_t) (n) + page_const) & ~page_const) | |
49 | ||
1cc651ec CF |
50 | static char *offsets[] = |
51 | { | |
52 | (char *) cygwin_shared_address, | |
53 | (char *) cygwin_shared_address | |
54 | + pround (sizeof (shared_info)), | |
55 | (char *) cygwin_shared_address | |
56 | + pround (sizeof (shared_info)) | |
57 | + pround (sizeof (mount_info)), | |
58 | (char *) cygwin_shared_address | |
59 | + pround (sizeof (shared_info)) | |
60 | + pround (sizeof (mount_info)) | |
61 | + pround (sizeof (console_state)), | |
62 | (char *) cygwin_shared_address | |
63 | + pround (sizeof (shared_info)) | |
64 | + pround (sizeof (mount_info)) | |
65 | + pround (sizeof (console_state)) | |
66 | + pround (sizeof (_pinfo)) | |
67 | }; | |
68 | ||
1fd5e000 | 69 | void * __stdcall |
fdb28b5e | 70 | open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, shared_locations m) |
1fd5e000 CF |
71 | { |
72 | void *shared; | |
fdb28b5e | 73 | |
6c6c3b90 CF |
74 | void *addr; |
75 | if (!wincap.needs_memory_protection ()) | |
76 | addr = NULL; | |
77 | else | |
fdb28b5e | 78 | { |
6c6c3b90 CF |
79 | addr = offsets[m]; |
80 | (void) VirtualFree (addr, 0, MEM_RELEASE); | |
fdb28b5e CF |
81 | } |
82 | ||
fdb28b5e CF |
83 | if (!size) |
84 | return addr; | |
1fd5e000 CF |
85 | |
86 | if (!shared_h) | |
87 | { | |
88 | char *mapname; | |
5c768c97 | 89 | char map_buf[MAX_PATH]; |
1fd5e000 CF |
90 | if (!name) |
91 | mapname = NULL; | |
92 | else | |
93 | { | |
5c768c97 | 94 | mapname = shared_name (map_buf, name, n); |
1fd5e000 CF |
95 | shared_h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE, |
96 | TRUE, mapname); | |
97 | } | |
98 | if (!shared_h && | |
580e99a1 CF |
99 | !(shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_all, |
100 | PAGE_READWRITE, 0, size, mapname))) | |
101 | api_fatal ("CreateFileMapping, %E. Terminating."); | |
1fd5e000 CF |
102 | } |
103 | ||
fdb28b5e CF |
104 | shared = (shared_info *) |
105 | MapViewOfFileEx (shared_h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, addr); | |
1fd5e000 CF |
106 | |
107 | if (!shared) | |
108 | { | |
109 | /* Probably win95, so try without specifying the address. */ | |
110 | shared = (shared_info *) MapViewOfFileEx (shared_h, | |
111 | FILE_MAP_READ|FILE_MAP_WRITE, | |
5457dfcb | 112 | 0, 0, 0, 0); |
5ec14fe4 CF |
113 | #ifdef DEBUGGING |
114 | if (wincap.is_winnt ()) | |
115 | system_printf ("relocating shared object %s(%d) from %p to %p on Windows NT", name, n, addr, shared); | |
116 | #endif | |
1fd5e000 CF |
117 | } |
118 | ||
119 | if (!shared) | |
2a6fc028 | 120 | api_fatal ("MapViewOfFileEx '%s'(%p), %E. Terminating.", name, shared_h); |
1fd5e000 | 121 | |
1cc651ec | 122 | if (m == SH_CYGWIN_SHARED && wincap.needs_memory_protection ()) |
6c6c3b90 | 123 | { |
1cc651ec CF |
124 | unsigned delta = (char *) shared - offsets[0]; |
125 | offsets[0] = (char *) shared; | |
6c6c3b90 CF |
126 | for (int i = SH_CYGWIN_SHARED + 1; i < SH_TOTAL_SIZE; i++) |
127 | { | |
1cc651ec CF |
128 | unsigned size = offsets[i + 1] - offsets[i]; |
129 | offsets[i] += delta; | |
130 | if (!VirtualAlloc (offsets[i], size, MEM_RESERVE, PAGE_NOACCESS)) | |
6c6c3b90 | 131 | continue; /* oh well */ |
6c6c3b90 | 132 | } |
1cc651ec | 133 | offsets[SH_TOTAL_SIZE] += delta; |
6c6c3b90 | 134 | |
d25c187f | 135 | #if 0 |
6c6c3b90 CF |
136 | if (!child_proc_info && wincap.needs_memory_protection ()) |
137 | for (DWORD s = 0x950000; s <= 0xa40000; s += 0x1000) | |
138 | VirtualAlloc ((void *) s, 4, MEM_RESERVE, PAGE_NOACCESS); | |
d25c187f | 139 | #endif |
6c6c3b90 CF |
140 | } |
141 | ||
2a6fc028 | 142 | debug_printf ("name %s, shared %p (wanted %p), h %p", name, shared, addr, shared_h); |
1fd5e000 | 143 | |
1fd5e000 CF |
144 | return shared; |
145 | } | |
146 | ||
147 | void | |
75119e99 | 148 | shared_info::initialize (const char *user_name) |
1fd5e000 | 149 | { |
75119e99 CF |
150 | DWORD sversion = (DWORD) InterlockedExchange ((LONG *) &version, SHARED_VERSION_MAGIC); |
151 | if (!sversion) | |
152 | { | |
153 | /* Initialize the queue of deleted files. */ | |
154 | delqueue.init (); | |
155 | ||
156 | /* Initialize tty table. */ | |
157 | tty.init (); | |
158 | } | |
159 | else | |
1fd5e000 | 160 | { |
aaf219f0 | 161 | if (version != SHARED_VERSION_MAGIC) |
75119e99 CF |
162 | { |
163 | multiple_cygwin_problem ("shared", version, SHARED_VERSION_MAGIC); | |
164 | InterlockedExchange ((LONG *) &version, sversion); | |
165 | } | |
166 | while (!cb) | |
167 | low_priority_sleep (0); // Should be hit only very very rarely | |
168 | } | |
169 | ||
170 | /* Initialize the Cygwin heap, if necessary */ | |
171 | if (!cygheap) | |
172 | { | |
173 | cygheap_init (); | |
174 | cygheap->user.set_name (user_name); | |
1fd5e000 CF |
175 | } |
176 | ||
75119e99 CF |
177 | heap_init (); |
178 | ||
179 | if (!sversion) | |
180 | cb = sizeof (*this); // Do last, after all shared memory initializion | |
1fd5e000 | 181 | |
aaf219f0 CF |
182 | if (cb != SHARED_INFO_CB) |
183 | system_printf ("size of shared memory region changed from %u to %u", | |
184 | SHARED_INFO_CB, cb); | |
1fd5e000 CF |
185 | } |
186 | ||
187 | void __stdcall | |
6a4878cf | 188 | memory_init () |
1fd5e000 | 189 | { |
fdb28b5e | 190 | getpagesize (); |
75119e99 CF |
191 | |
192 | char user_name[UNLEN + 1]; | |
193 | DWORD user_name_len = UNLEN + 1; | |
194 | ||
195 | if (!GetUserName (user_name, &user_name_len)) | |
196 | strcpy (user_name, "unknown"); | |
197 | ||
6a4878cf | 198 | /* Initialize general shared memory */ |
2a6fc028 CF |
199 | HANDLE shared_h = cygheap ? cygheap->shared_h : NULL; |
200 | cygwin_shared = (shared_info *) open_shared ("shared", | |
a9f20457 | 201 | CYGWIN_VERSION_SHARED_DATA, |
2a6fc028 CF |
202 | shared_h, |
203 | sizeof (*cygwin_shared), | |
fdb28b5e | 204 | SH_CYGWIN_SHARED); |
2a6fc028 | 205 | |
75119e99 | 206 | cygwin_shared->initialize (user_name); |
1ff9f4b9 | 207 | |
2a6fc028 | 208 | cygheap->shared_h = shared_h; |
0301bfd0 | 209 | ProtectHandleINH (cygheap->shared_h); |
6a4878cf | 210 | |
75119e99 | 211 | /* Allocate memory for the per-user mount table */ |
a9f20457 | 212 | mount_table = (mount_info *) open_shared (user_name, MOUNT_VERSION, |
54030e21 | 213 | cygwin_mount_h, sizeof (mount_info), |
fdb28b5e | 214 | SH_MOUNT_TABLE); |
1ff9f4b9 | 215 | debug_printf ("opening mount table for '%s' at %p", cygheap->user.name (), |
fdb28b5e | 216 | mount_table); |
0301bfd0 | 217 | ProtectHandleINH (cygwin_mount_h); |
1ff9f4b9 CF |
218 | debug_printf ("mount table version %x at %p", mount_table->version, mount_table); |
219 | ||
6a4878cf CF |
220 | /* Initialize the Cygwin per-user mount table, if necessary */ |
221 | if (!mount_table->version) | |
222 | { | |
77f4a250 | 223 | mount_table->version = MOUNT_VERSION_MAGIC; |
6a4878cf | 224 | debug_printf ("initializing mount table"); |
aaf219f0 CF |
225 | mount_table->cb = sizeof (*mount_table); |
226 | if (mount_table->cb != MOUNT_INFO_CB) | |
227 | system_printf ("size of mount table region changed from %u to %u", | |
228 | MOUNT_INFO_CB, mount_table->cb); | |
6a4878cf CF |
229 | mount_table->init (); /* Initialize the mount table. */ |
230 | } | |
77f4a250 CF |
231 | else if (mount_table->version != MOUNT_VERSION_MAGIC) |
232 | multiple_cygwin_problem ("mount", mount_table->version, MOUNT_VERSION); | |
aaf219f0 CF |
233 | else if (mount_table->cb != MOUNT_INFO_CB) |
234 | multiple_cygwin_problem ("mount table size", mount_table->cb, MOUNT_INFO_CB); | |
a9f20457 | 235 | |
1fd5e000 CF |
236 | } |
237 | ||
1fd5e000 CF |
238 | unsigned |
239 | shared_info::heap_chunk_size () | |
240 | { | |
1cc651ec | 241 | if (!heap_chunk) |
de05a524 CF |
242 | { |
243 | /* Fetch misc. registry entries. */ | |
244 | ||
245 | reg_key reg (KEY_READ, NULL); | |
246 | ||
247 | /* Note that reserving a huge amount of heap space does not result in | |
248 | the use of swap since we are not committing it. */ | |
249 | /* FIXME: We should not be restricted to a fixed size heap no matter | |
250 | what the fixed size is. */ | |
251 | ||
1cc651ec CF |
252 | heap_chunk = reg.get_int ("heap_chunk_in_mb", 0); |
253 | if (!heap_chunk) { | |
60bc7b59 CF |
254 | reg_key r1 (HKEY_LOCAL_MACHINE, KEY_READ, "SOFTWARE", |
255 | CYGWIN_INFO_CYGNUS_REGISTRY_NAME, | |
256 | CYGWIN_INFO_CYGWIN_REGISTRY_NAME, NULL); | |
485d85bf | 257 | heap_chunk = r1.get_int ("heap_chunk_in_mb", 384); |
60bc7b59 CF |
258 | } |
259 | ||
1cc651ec CF |
260 | if (heap_chunk < 4) |
261 | heap_chunk = 4 * 1024 * 1024; | |
60bc7b59 | 262 | else |
1cc651ec | 263 | heap_chunk <<= 20; |
f51e42ac CF |
264 | if (!heap_chunk) |
265 | heap_chunk = 384 * 1024 * 1024; | |
1cc651ec | 266 | debug_printf ("fixed heap size is %u", heap_chunk); |
de05a524 CF |
267 | } |
268 | ||
1cc651ec | 269 | return heap_chunk; |
1fd5e000 | 270 | } |