]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/shared.cc
* exceptions.cc (set_process_mask): Set pending signals only when signals
[newlib-cygwin.git] / winsup / cygwin / shared.cc
CommitLineData
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
5This file is part of Cygwin.
6
7This software is a copyrighted work licensed under the terms of the
8Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9details. */
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
30shared_info NO_COPY *cygwin_shared;
31mount_info NO_COPY *mount_table;
e851d2fe 32HANDLE NO_COPY cygwin_mount_h;
1fd5e000 33
1fd5e000 34char * __stdcall
5c768c97 35shared_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
50static 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 69void * __stdcall
fdb28b5e 70open_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
147void
75119e99 148shared_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
187void __stdcall
6a4878cf 188memory_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
238unsigned
239shared_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}
This page took 0.509751 seconds and 5 git commands to generate.