OSDN Git Service

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