OSDN Git Service

* cygheap.cc (cfree_and_set): New function.
[pf3gnuchains/sourceware.git] / winsup / cygwin / cygheap.h
1 /* cygheap.h: Cygwin heap manager.
2
3    Copyright 2000, 2001, 2002 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_1_START,
21   HEAP_1_STR,
22   HEAP_1_ARGV,
23   HEAP_1_BUF,
24   HEAP_1_EXEC,
25   HEAP_1_MAX = 100
26 };
27
28 #define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap_max)))
29
30 struct _cmalloc_entry
31 {
32   union
33   {
34     DWORD b;
35     char *ptr;
36   };
37   struct _cmalloc_entry *prev;
38   char data[0];
39 };
40
41 struct cygheap_root_mount_info
42 {
43   char posix_path[MAX_PATH];
44   unsigned posix_pathlen;
45   char native_path[MAX_PATH];
46   unsigned native_pathlen;
47 };
48
49 /* CGF: FIXME This doesn't belong here */
50
51 class cygheap_root
52 {
53   /* Root directory information.
54      This is used after a chroot is called. */
55   struct cygheap_root_mount_info *m;
56
57 public:
58   bool posix_ok (const char *path)
59   {
60     if (!m)
61       return 1;
62     return path_prefix_p (m->posix_path, path, m->posix_pathlen);
63   }
64   bool ischroot_native (const char *path)
65   {
66     if (!m)
67       return 1;
68     return strncasematch (m->native_path, path, m->native_pathlen)
69             && (path[m->native_pathlen] == '\\' || !path[m->native_pathlen]);
70   }
71   const char *unchroot (const char *path)
72   {
73     if (!m)
74       return path;
75     const char *p = path + m->posix_pathlen;
76     if (!*p)
77       p = "/";
78     return p;
79   }
80   bool exists () {return !!m;}
81   void set (const char *posix, const char *native);
82   size_t posix_length () const { return m->posix_pathlen; }
83   const char *posix_path () const { return m->posix_path; }
84   size_t native_length () const { return m->native_pathlen; }
85   const char *native_path () const { return m->native_path; }
86 };
87
88 enum homebodies
89 {
90   CH_HOMEDRIVE,
91   CH_HOMEPATH,
92   CH_HOME
93 };
94
95 struct passwd;
96 class cygheap_user
97 {
98   /* Extendend user information.
99      The information is derived from the internal_getlogin call
100      when on a NT system. */
101   char  *pname;         /* user's name */
102   char  *plogsrv;       /* Logon server, may be FQDN */
103   char  *pdomain;       /* Logon domain of the user */
104   char  *homedrive;     /* User's home drive */
105   char  *homepath;      /* User's home path */
106   char  *winname;       /* User's name as far as Windows knows it */
107   char  *puserprof;     /* User profile */
108   PSID   psid;          /* buffer for user's SID */
109   PSID   orig_psid;     /* Remains intact even after impersonation */
110 public:
111   __uid32_t orig_uid;      /* Remains intact even after impersonation */
112   __gid32_t orig_gid;      /* Ditto */
113   __uid32_t real_uid;      /* Remains intact on seteuid, replaced by setuid */
114   __gid32_t real_gid;      /* Ditto */
115
116   /* token is needed if set(e)uid should be called. It can be set by a call
117      to `set_impersonation_token()'. */
118   HANDLE token;
119   BOOL   impersonated;
120
121   /* CGF 2002-06-27.  I removed the initializaton from this constructor
122      since this class is always allocated statically.  That means that everything
123      is zero anyway so there is no need to initialize it to zero.  Since the
124      token initialization is always handled during process startup as well,
125      I've removed the constructor entirely.  Please reinstate this f this
126      situation ever changes.
127   cygheap_user () : pname (NULL), plogsrv (NULL), pdomain (NULL),
128                     homedrive (NULL), homepath (NULL), psid (NULL),
129                     token (INVALID_HANDLE_VALUE) {}
130   */
131
132   ~cygheap_user ();
133
134   void set_name (const char *new_name);
135   const char *name () const { return pname; }
136
137   const char *env_logsrv ();
138   const char *env_homepath ();
139   const char *env_homedrive ();
140   const char *env_userprofile ();
141   const char *env_domain ();
142   const char *env_name ();
143
144   BOOL set_sid (PSID new_sid);
145   BOOL set_orig_sid ();
146   PSID sid () const { return psid; }
147   PSID orig_sid () const { return orig_psid; }
148   const char *ontherange (homebodies what, struct passwd * = NULL);
149   bool issetuid () const
150   {
151     return impersonated && token != INVALID_HANDLE_VALUE;
152   }
153 };
154
155 /* cwd cache stuff.  */
156
157 class muto;
158
159 struct cwdstuff
160 {
161   char *posix;
162   char *win32;
163   DWORD hash;
164   muto *cwd_lock;
165   char *get (char *buf, int need_posix = 1, int with_chroot = 0, unsigned ulen = MAX_PATH);
166   DWORD get_hash ();
167   void init ();
168   void fixup_after_exec (char *win32, char *posix, DWORD hash);
169   bool get_initial ();
170   void set (const char *win32_cwd, const char *posix_cwd = NULL);
171 };
172
173 struct init_cygheap
174 {
175   _cmalloc_entry *chain;
176   char *buckets[32];
177   struct /* User heap stuff. */
178     {
179       void *heapbase;
180       void *heapptr;
181       void *heaptop;
182     };
183   cygheap_root root;
184   cygheap_user user;
185   mode_t umask;
186   HANDLE shared_h;
187   HANDLE console_h;
188   HANDLE etc_changed_h;
189   char *cygwin_regname;
190   cwdstuff cwd;
191   dtable fdtab;
192
193   bool etc_changed ();
194 };
195
196 #define CYGHEAPSIZE (sizeof (init_cygheap) + (4000 * sizeof (fhandler_union)) + (2 * 65536))
197
198 extern init_cygheap *cygheap;
199 extern void *cygheap_max;
200
201 class cygheap_fdmanip
202 {
203  protected:
204   int fd;
205   fhandler_base **fh;
206   bool locked;
207  public:
208   cygheap_fdmanip (): fh (NULL) {}
209   virtual ~cygheap_fdmanip ()
210   {
211     if (locked)
212       ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdmanip");
213   }
214   void release ()
215   {
216     cygheap->fdtab.release (fd);
217   }
218   operator int &() {return fd;}
219   operator fhandler_base* &() {return *fh;}
220   void operator = (fhandler_base *fh) {*this->fh = fh;}
221   fhandler_base *operator -> () const {return *fh;}
222   bool isopen () const
223   {
224     if (*fh)
225       return true;
226     set_errno (EBADF);
227     return false;
228   }
229 };
230
231 class cygheap_fdnew : public cygheap_fdmanip
232 {
233  public:
234   cygheap_fdnew (int seed_fd = -1, bool lockit = true)
235   {
236     if (lockit)
237       SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
238     if (seed_fd < 0)
239       fd = cygheap->fdtab.find_unused_handle ();
240     else
241       fd = cygheap->fdtab.find_unused_handle (seed_fd + 1);
242     if (fd >= 0)
243       {
244         locked = lockit;
245         fh = cygheap->fdtab + fd;
246       }
247     else
248       {
249         set_errno (EMFILE);
250         if (lockit)
251           ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
252         locked = false;
253       }
254   }
255   void operator = (fhandler_base *fh) {*this->fh = fh;}
256 };
257
258 class cygheap_fdget : public cygheap_fdmanip
259 {
260  public:
261   cygheap_fdget (int fd, bool lockit = false, bool do_set_errno = true)
262   {
263     if (lockit)
264       SetResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
265     if (fd >= 0 && fd < (int) cygheap->fdtab.size
266         && *(fh = cygheap->fdtab + fd) != NULL)
267       {
268         this->fd = fd;
269         locked = lockit;
270       }
271     else
272       {
273         this->fd = -1;
274         if (do_set_errno)
275           set_errno (EBADF);
276         if (lockit)
277           ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
278         locked = false;
279       }
280   }
281 };
282
283 class child_info;
284 void *__stdcall cygheap_setup_for_child (child_info *ci, bool dup_later) __attribute__ ((regparm(2)));
285 void __stdcall cygheap_setup_for_child_cleanup (void *, child_info *, bool) __attribute__ ((regparm(3)));
286 void __stdcall cygheap_fixup_in_child (bool);
287 extern "C" {
288 void __stdcall cfree (void *) __attribute__ ((regparm(1)));
289 void *__stdcall cmalloc (cygheap_types, DWORD) __attribute__ ((regparm(2)));
290 void *__stdcall crealloc (void *, DWORD) __attribute__ ((regparm(2)));
291 void *__stdcall ccalloc (cygheap_types, DWORD, DWORD) __attribute__ ((regparm(3)));
292 char *__stdcall cstrdup (const char *) __attribute__ ((regparm(1)));
293 char *__stdcall cstrdup1 (const char *) __attribute__ ((regparm(1)));
294 void __stdcall cfree_and_set (char *&, char * = NULL) __attribute__ ((regparm(2)));
295 void __stdcall cygheap_init ();
296 }