]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/cygheap.h
2004-10-28 Pierre Humblet <pierre.humblet@ieee.org>
[newlib-cygwin.git] / winsup / cygwin / cygheap.h
CommitLineData
b0e82b74
CF
1/* cygheap.h: Cygwin heap manager.
2
85dde362 3 Copyright 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
b0e82b74
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
11#undef cfree
12
13enum cygheap_types
14{
15 HEAP_FHANDLER,
16 HEAP_STR,
17 HEAP_ARGV,
e5648465 18 HEAP_BUF,
7ceb1cac 19 HEAP_MOUNT,
c0a9bffd 20 HEAP_SIGS,
8e10c431 21 HEAP_ARCHETYPES,
2d1d1eb1 22 HEAP_TLS,
e5648465
CF
23 HEAP_1_START,
24 HEAP_1_STR,
25 HEAP_1_ARGV,
26 HEAP_1_BUF,
8d82847a 27 HEAP_1_EXEC,
5c6497b4
CF
28 HEAP_1_MAX = 100,
29 HEAP_MMAP = 200
b0e82b74
CF
30};
31
9fc09d00 32#define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap_max)))
b0e82b74 33
a4785603
CF
34struct _cmalloc_entry
35{
36 union
37 {
38 DWORD b;
39 char *ptr;
40 };
41 struct _cmalloc_entry *prev;
42 char data[0];
43};
44
7ceb1cac
CF
45struct cygheap_root_mount_info
46{
95d02d5b 47 char posix_path[CYG_MAX_PATH];
7ceb1cac 48 unsigned posix_pathlen;
95d02d5b 49 char native_path[CYG_MAX_PATH];
7ceb1cac
CF
50 unsigned native_pathlen;
51};
52
ac5561f2
CF
53/* CGF: FIXME This doesn't belong here */
54
1f0f8e12
CV
55class cygheap_root
56{
57 /* Root directory information.
58 This is used after a chroot is called. */
7ceb1cac
CF
59 struct cygheap_root_mount_info *m;
60
1f0f8e12 61public:
7ceb1cac
CF
62 bool posix_ok (const char *path)
63 {
7ceb1cac
CF
64 if (!m)
65 return 1;
66 return path_prefix_p (m->posix_path, path, m->posix_pathlen);
67 }
68 bool ischroot_native (const char *path)
69 {
70 if (!m)
71 return 1;
72 return strncasematch (m->native_path, path, m->native_pathlen)
1ff9f4b9 73 && (path[m->native_pathlen] == '\\' || !path[m->native_pathlen]);
7ceb1cac
CF
74 }
75 const char *unchroot (const char *path)
76 {
77 if (!m)
78 return path;
79 const char *p = path + m->posix_pathlen;
80 if (!*p)
81 p = "/";
82 return p;
83 }
84 bool exists () {return !!m;}
71af2ed3 85 void set (const char *, const char *);
7ceb1cac
CF
86 size_t posix_length () const { return m->posix_pathlen; }
87 const char *posix_path () const { return m->posix_path; }
88 size_t native_length () const { return m->native_pathlen; }
89 const char *native_path () const { return m->native_path; }
1f0f8e12
CV
90};
91
da086d02
CF
92enum homebodies
93{
94 CH_HOMEDRIVE,
95 CH_HOMEPATH,
96 CH_HOME
97};
98
a7cde2b9
CF
99class cygheap_user
100{
1f0f8e12
CV
101 /* Extendend user information.
102 The information is derived from the internal_getlogin call
103 when on a NT system. */
66c161ba
CV
104 char *pname; /* user's name */
105 char *plogsrv; /* Logon server, may be FQDN */
106 char *pdomain; /* Logon domain of the user */
da086d02
CF
107 char *homedrive; /* User's home drive */
108 char *homepath; /* User's home path */
60cb120f 109 char *psystemroot; /* Value of SYSTEMROOT */
094d5193 110 char *pwinname; /* User's name as far as Windows knows it */
179cae11 111 char *puserprof; /* User profile */
6806a8b5
PH
112 cygsid effec_cygsid; /* buffer for user's SID */
113 cygsid saved_cygsid; /* Remains intact even after impersonation */
1f0f8e12 114public:
1498189c
CV
115 __uid32_t saved_uid; /* Remains intact even after impersonation */
116 __gid32_t saved_gid; /* Ditto */
a8d7ae61 117 __uid32_t real_uid; /* Remains intact on seteuid, replaced by setuid */
57196405 118 __gid32_t real_gid; /* Ditto */
5519d543 119 user_groups groups; /* Primary and supp SIDs */
1f0f8e12 120
66c161ba
CV
121 /* token is needed if set(e)uid should be called. It can be set by a call
122 to `set_impersonation_token()'. */
70249d56
CV
123 HANDLE external_token;
124 HANDLE internal_token;
ea3ba114 125 HANDLE current_token;
66c161ba 126
179cae11
CF
127 /* CGF 2002-06-27. I removed the initializaton from this constructor
128 since this class is always allocated statically. That means that everything
129 is zero anyway so there is no need to initialize it to zero. Since the
130 token initialization is always handled during process startup as well,
2e008fb9 131 I've removed the constructor entirely. Please reinstate this if this
179cae11 132 situation ever changes.
f7fa593d 133 cygheap_user () : pname (NULL), plogsrv (NULL), pdomain (NULL),
1498189c 134 homedrive (NULL), homepath (NULL),
179cae11
CF
135 token (INVALID_HANDLE_VALUE) {}
136 */
137
1f0f8e12
CV
138 ~cygheap_user ();
139
0efafbfb 140 void init ();
1f0f8e12
CV
141 void set_name (const char *new_name);
142 const char *name () const { return pname; }
143
094d5193
CF
144 const char *env_logsrv (const char *, size_t);
145 const char *env_homepath (const char *, size_t);
146 const char *env_homedrive (const char *, size_t);
147 const char *env_userprofile (const char *, size_t);
148 const char *env_domain (const char *, size_t);
149 const char *env_name (const char *, size_t);
60cb120f 150 const char *env_systemroot (const char *, size_t);
1f0f8e12 151
094d5193
CF
152 const char *logsrv ()
153 {
efc1575e
CF
154 const char *p = env_logsrv ("LOGONSERVER=", sizeof ("LOGONSERVER=") - 1);
155 return (p == almost_null) ? NULL : p;
094d5193
CF
156 }
157 const char *winname ()
158 {
efc1575e
CF
159 const char *p = env_name ("USERNAME=", sizeof ("USERNAME=") - 1);
160 return (p == almost_null) ? NULL : p;
094d5193
CF
161 }
162 const char *domain ()
163 {
efc1575e
CF
164 const char *p = env_domain ("USERDOMAIN=", sizeof ("USERDOMAIN=") - 1);
165 return (p == almost_null) ? NULL : p;
094d5193 166 }
6806a8b5
PH
167 BOOL set_sid (PSID new_sid) {return (BOOL) (effec_cygsid = new_sid);}
168 BOOL set_saved_sid () { return (BOOL) (saved_cygsid = effec_cygsid); }
169 PSID sid () { return effec_cygsid; }
170 PSID saved_sid () { return saved_cygsid; }
da086d02 171 const char *ontherange (homebodies what, struct passwd * = NULL);
53197923
PH
172#define NO_IMPERSONATION NULL
173 bool issetuid () const { return current_token != NO_IMPERSONATION; }
ea3ba114 174 HANDLE token () { return current_token; }
70249d56
CV
175 void deimpersonate ()
176 {
ea3ba114 177 if (issetuid ())
70249d56
CV
178 RevertToSelf ();
179 }
180 void reimpersonate ()
181 {
ea3ba114 182 if (issetuid ()
70249d56
CV
183 && !ImpersonateLoggedOnUser (token ()))
184 system_printf ("ImpersonateLoggedOnUser: %E");
185 }
ea3ba114 186 bool has_impersonation_tokens ()
53197923
PH
187 { return external_token != NO_IMPERSONATION
188 || internal_token != NO_IMPERSONATION
189 || current_token != NO_IMPERSONATION; }
70249d56
CV
190 void close_impersonation_tokens ()
191 {
53197923 192 if (current_token != NO_IMPERSONATION)
ea3ba114
CV
193 {
194 if( current_token != external_token && current_token != internal_token)
195 CloseHandle (current_token);
53197923 196 current_token = NO_IMPERSONATION;
ea3ba114 197 }
53197923 198 if (external_token != NO_IMPERSONATION)
70249d56
CV
199 {
200 CloseHandle (external_token);
53197923 201 external_token = NO_IMPERSONATION;
70249d56 202 }
53197923 203 if (internal_token != NO_IMPERSONATION)
70249d56
CV
204 {
205 CloseHandle (internal_token);
53197923 206 internal_token = NO_IMPERSONATION;
70249d56 207 }
e40670ee 208 }
094d5193
CF
209 const char *cygheap_user::test_uid (char *&, const char *, size_t)
210 __attribute__ ((regparm (3)));
1f0f8e12 211};
a4785603 212
431ba7dd
CF
213/* cwd cache stuff. */
214
215class muto;
216
217struct cwdstuff
218{
219 char *posix;
220 char *win32;
221 DWORD hash;
a4563209 222 DWORD drive_length;
083abe54 223 muto *cwd_lock;
71af2ed3 224 char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH);
431ba7dd 225 DWORD get_hash ();
a4563209
PH
226 DWORD get_drive (char * dst)
227 {
228 get_initial ();
229 memcpy (dst, win32, drive_length);
230 return drive_length;
231 }
431ba7dd 232 void init ();
71af2ed3 233 void fixup_after_exec (char *, char *, DWORD);
431ba7dd 234 bool get_initial ();
71af2ed3 235 int set (const char *, const char *, bool);
431ba7dd
CF
236};
237
0301bfd0
CF
238#ifdef DEBUGGING
239struct cygheap_debug
240{
241 handle_list starth;
242 handle_list *endh;
243 handle_list freeh[500];
244};
245#endif
246
1cc651ec
CF
247struct user_heap_info
248{
249 void *base;
250 void *ptr;
251 void *top;
897c6b52 252 void *max;
1cc651ec
CF
253 unsigned chunk;
254};
255
a4785603
CF
256struct init_cygheap
257{
258 _cmalloc_entry *chain;
4ce15a49 259 char *buckets[32];
1f0f8e12
CV
260 cygheap_root root;
261 cygheap_user user;
1cc651ec 262 user_heap_info user_heap;
a4785603 263 mode_t umask;
2a6fc028
CF
264 HANDLE shared_h;
265 HANDLE console_h;
191ea07a 266 HANDLE mt_h;
a9f20457 267 char *cygwin_regname;
431ba7dd 268 cwdstuff cwd;
0381fec6 269 dtable fdtab;
6c2b7846 270 const char *shared_prefix;
0301bfd0
CF
271#ifdef DEBUGGING
272 cygheap_debug debug;
273#endif
c0a9bffd 274 struct sigaction *sigs;
2e008fb9 275
8e10c431 276 fhandler_tty_slave *ctty; /* Current tty */
f7239090 277#ifdef NEWVFORK
e80cbe3e 278 fhandler_tty_slave *ctty_on_hold;
f7239090 279#endif
e431827c 280 struct _cygtls **threadlist;
2d1d1eb1 281 size_t sthreads;
8ed5c9b6 282 int open_fhs;
d584454c 283 pid_t pid; /* my pid */
2d1d1eb1 284 void close_ctty ();
a4785603
CF
285};
286
0cb38eb5 287#define _CYGHEAPSIZE_SLOP (128 * 1024)
d8f87fba
CF
288#define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + _CYGHEAPSIZE_SLOP)
289#define CYGHEAPSIZE_MIN (sizeof (init_cygheap) + (10000 * sizeof (fhandler_union)))
0381fec6 290
a4785603
CF
291extern init_cygheap *cygheap;
292extern void *cygheap_max;
293
df63bd49
CF
294class cygheap_fdmanip
295{
296 protected:
297 int fd;
298 fhandler_base **fh;
299 bool locked;
300 public:
6ea0c04e 301 cygheap_fdmanip (): fh (NULL) {}
df63bd49
CF
302 virtual ~cygheap_fdmanip ()
303 {
304 if (locked)
2d1d1eb1 305 cygheap->fdtab.unlock ();
df63bd49
CF
306 }
307 void release ()
308 {
309 cygheap->fdtab.release (fd);
310 }
311 operator int &() {return fd;}
312 operator fhandler_base* &() {return *fh;}
7ac61736 313 operator fhandler_socket* () const {return reinterpret_cast<fhandler_socket *> (*fh);}
df63bd49
CF
314 void operator = (fhandler_base *fh) {*this->fh = fh;}
315 fhandler_base *operator -> () const {return *fh;}
53f00290
CF
316 bool isopen () const
317 {
318 if (*fh)
319 return true;
320 set_errno (EBADF);
321 return false;
322 }
df63bd49
CF
323};
324
325class cygheap_fdnew : public cygheap_fdmanip
326{
327 public:
328 cygheap_fdnew (int seed_fd = -1, bool lockit = true)
329 {
330 if (lockit)
2d1d1eb1 331 cygheap->fdtab.lock ();
df63bd49
CF
332 if (seed_fd < 0)
333 fd = cygheap->fdtab.find_unused_handle ();
334 else
335 fd = cygheap->fdtab.find_unused_handle (seed_fd + 1);
336 if (fd >= 0)
337 {
338 locked = lockit;
339 fh = cygheap->fdtab + fd;
340 }
341 else
342 {
343 set_errno (EMFILE);
344 if (lockit)
2d1d1eb1 345 cygheap->fdtab.unlock ();
df63bd49
CF
346 locked = false;
347 }
348 }
7903ee69 349 void operator = (fhandler_base *fh) {*this->fh = fh;}
df63bd49
CF
350};
351
352class cygheap_fdget : public cygheap_fdmanip
353{
354 public:
0f4db8cb 355 cygheap_fdget (int fd, bool lockit = false, bool do_set_errno = true)
df63bd49
CF
356 {
357 if (lockit)
2d1d1eb1 358 cygheap->fdtab.lock ();
df63bd49
CF
359 if (fd >= 0 && fd < (int) cygheap->fdtab.size
360 && *(fh = cygheap->fdtab + fd) != NULL)
361 {
362 this->fd = fd;
363 locked = lockit;
364 }
365 else
366 {
367 this->fd = -1;
0f4db8cb 368 if (do_set_errno)
2ac3bab6 369 set_errno (EBADF);
df63bd49 370 if (lockit)
2d1d1eb1 371 cygheap->fdtab.unlock ();
df63bd49
CF
372 locked = false;
373 }
374 }
375};
376
5457dfcb 377class child_info;
e2e07827
CF
378void *__stdcall cygheap_setup_for_child (child_info *ci, bool dup_later) __attribute__ ((regparm(2)));
379void __stdcall cygheap_setup_for_child_cleanup (void *, child_info *, bool) __attribute__ ((regparm(3)));
6ea3e429 380void __stdcall cygheap_fixup_in_child (bool);
b0e82b74 381extern "C" {
166b2571 382void __stdcall cfree (void *) __attribute__ ((regparm(1)));
166b2571
CF
383void *__stdcall cmalloc (cygheap_types, DWORD) __attribute__ ((regparm(2)));
384void *__stdcall crealloc (void *, DWORD) __attribute__ ((regparm(2)));
385void *__stdcall ccalloc (cygheap_types, DWORD, DWORD) __attribute__ ((regparm(3)));
386char *__stdcall cstrdup (const char *) __attribute__ ((regparm(1)));
387char *__stdcall cstrdup1 (const char *) __attribute__ ((regparm(1)));
179cae11 388void __stdcall cfree_and_set (char *&, char * = NULL) __attribute__ ((regparm(2)));
9fc09d00 389void __stdcall cygheap_init ();
6d8bd861 390extern DWORD _cygheap_start;
1ed8d187 391}
This page took 0.204514 seconds and 5 git commands to generate.