OSDN Git Service

* cygtls.h (_threadinfo::call): Remove regparm declaration to work around
[pf3gnuchains/sourceware.git] / winsup / cygwin / cygheap.h
index 032f6a4..be51527 100644 (file)
@@ -1,6 +1,6 @@
 /* cygheap.h: Cygwin heap manager.
 
-   Copyright 2000, 2001, 2002 Red Hat, Inc.
+   Copyright 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -17,12 +17,16 @@ enum cygheap_types
   HEAP_ARGV,
   HEAP_BUF,
   HEAP_MOUNT,
+  HEAP_SIGS,
+  HEAP_ARCHETYPES,
+  HEAP_TLS,
   HEAP_1_START,
   HEAP_1_STR,
   HEAP_1_ARGV,
   HEAP_1_BUF,
   HEAP_1_EXEC,
-  HEAP_1_MAX = 100
+  HEAP_1_MAX = 100,
+  HEAP_MMAP = 200
 };
 
 #define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap_max)))
@@ -40,9 +44,9 @@ struct _cmalloc_entry
 
 struct cygheap_root_mount_info
 {
-  char posix_path[MAX_PATH];
+  char posix_path[CYG_MAX_PATH];
   unsigned posix_pathlen;
-  char native_path[MAX_PATH];
+  char native_path[CYG_MAX_PATH];
   unsigned native_pathlen;
 };
 
@@ -92,7 +96,6 @@ enum homebodies
   CH_HOME
 };
 
-struct passwd;
 class cygheap_user
 {
   /* Extendend user information.
@@ -103,47 +106,105 @@ class cygheap_user
   char  *pdomain;       /* Logon domain of the user */
   char  *homedrive;    /* User's home drive */
   char  *homepath;     /* User's home path */
-  char  *winname;      /* User's name as far as Windows knows it */
-  PSID   psid;          /* buffer for user's SID */
-  PSID   orig_psid;     /* Remains intact even after impersonation */
-  static char homedrive_env_buf[3]; /* Where the HOMEDRIVE environment variable
-                                      info may live. */
-  static char homepath_env_buf[MAX_PATH + 1]; /* Where the HOMEPATH environment
-                                                variable info may live. */
-  static char userprofile_env_buf[MAX_PATH + 1]; /* Where the USERPROFILE
-                                                   environment variable info
-                                                   may live. */
+  char  *pwinname;     /* User's name as far as Windows knows it */
+  char  *puserprof;    /* User profile */
+  cygsid effec_cygsid;  /* buffer for user's SID */
+  cygsid saved_cygsid;  /* Remains intact even after impersonation */
 public:
-  __uid32_t orig_uid;      /* Remains intact even after impersonation */
-  __gid32_t orig_gid;      /* Ditto */
+  __uid32_t saved_uid;     /* Remains intact even after impersonation */
+  __gid32_t saved_gid;     /* Ditto */
   __uid32_t real_uid;      /* Remains intact on seteuid, replaced by setuid */
   __gid32_t real_gid;      /* Ditto */
+  user_groups groups;      /* Primary and supp SIDs */
 
   /* token is needed if set(e)uid should be called. It can be set by a call
      to `set_impersonation_token()'. */
-  HANDLE token;
-  BOOL   impersonated;
+  HANDLE external_token;
+  HANDLE internal_token;
+  HANDLE current_token;
 
+  /* CGF 2002-06-27.  I removed the initializaton from this constructor
+     since this class is always allocated statically.  That means that everything
+     is zero anyway so there is no need to initialize it to zero.  Since the
+     token initialization is always handled during process startup as well,
+     I've removed the constructor entirely.  Please reinstate this if this
+     situation ever changes.
   cygheap_user () : pname (NULL), plogsrv (NULL), pdomain (NULL),
                    homedrive (NULL), homepath (NULL),
-                   psid (NULL), token (INVALID_HANDLE_VALUE) {}
+                   token (INVALID_HANDLE_VALUE) {}
+  */
+
   ~cygheap_user ();
 
+  void init ();
   void set_name (const char *new_name);
   const char *name () const { return pname; }
 
-  const char *env_logsrv ();
-  const char *env_homepath ();
-  const char *env_homedrive ();
-  const char *env_userprofile ();
-  const char *env_domain ();
-  const char *env_name ();
-
-  BOOL set_sid (PSID new_sid);
-  BOOL set_orig_sid ();
-  PSID sid () const { return psid; }
-  PSID orig_sid () const { return orig_psid; }
+  const char *env_logsrv (const char *, size_t);
+  const char *env_homepath (const char *, size_t);
+  const char *env_homedrive (const char *, size_t);
+  const char *env_userprofile (const char *, size_t);
+  const char *env_domain (const char *, size_t);
+  const char *env_name (const char *, size_t);
+
+  const char *logsrv ()
+  {
+    const char *p = env_logsrv ("LOGONSERVER=", sizeof ("LOGONSERVER=") - 1);
+    return (p == almost_null) ? NULL : p;
+  }
+  const char *winname ()
+  {
+    const char *p = env_name ("USERNAME=", sizeof ("USERNAME=") - 1);
+    return (p == almost_null) ? NULL : p;
+  }
+  const char *domain ()
+  {
+    const char *p = env_domain ("USERDOMAIN=", sizeof ("USERDOMAIN=") - 1);
+    return (p == almost_null) ? NULL : p;
+  }
+  BOOL set_sid (PSID new_sid) {return (BOOL) (effec_cygsid = new_sid);}
+  BOOL set_saved_sid () { return (BOOL) (saved_cygsid = effec_cygsid); }
+  PSID sid () { return effec_cygsid; }
+  PSID saved_sid () { return saved_cygsid; }
   const char *ontherange (homebodies what, struct passwd * = NULL);
+  bool issetuid () const { return current_token != INVALID_HANDLE_VALUE; }
+  HANDLE token () { return current_token; }
+  void deimpersonate ()
+  {
+    if (issetuid ())
+      RevertToSelf ();
+  }
+  void reimpersonate ()
+  {
+    if (issetuid ()
+       && !ImpersonateLoggedOnUser (token ()))
+      system_printf ("ImpersonateLoggedOnUser: %E");
+  }
+  bool has_impersonation_tokens ()
+    { return external_token != INVALID_HANDLE_VALUE
+             || internal_token != INVALID_HANDLE_VALUE
+            || current_token != INVALID_HANDLE_VALUE; }
+  void close_impersonation_tokens ()
+  {
+    if (current_token != INVALID_HANDLE_VALUE)
+      {
+       if( current_token != external_token && current_token != internal_token)
+         CloseHandle (current_token);
+       current_token = INVALID_HANDLE_VALUE;
+      }
+    if (external_token != INVALID_HANDLE_VALUE)
+      {
+       CloseHandle (external_token);
+       external_token = INVALID_HANDLE_VALUE;
+      }
+    if (internal_token != INVALID_HANDLE_VALUE)
+      {
+       CloseHandle (internal_token);
+       internal_token = INVALID_HANDLE_VALUE;
+      }
+  }
+  const char *cygheap_user::test_uid (char *&, const char *, size_t)
+    __attribute__ ((regparm (3)));
 };
 
 /* cwd cache stuff.  */
@@ -156,7 +217,7 @@ struct cwdstuff
   char *win32;
   DWORD hash;
   muto *cwd_lock;
-  char *get (char *buf, int need_posix = 1, int with_chroot = 0, unsigned ulen = MAX_PATH);
+  char *get (char *buf, int need_posix = 1, int with_chroot = 0, unsigned ulen = CYG_MAX_PATH);
   DWORD get_hash ();
   void init ();
   void fixup_after_exec (char *win32, char *posix, DWORD hash);
@@ -164,30 +225,52 @@ struct cwdstuff
   void set (const char *win32_cwd, const char *posix_cwd = NULL);
 };
 
+#ifdef DEBUGGING
+struct cygheap_debug
+{
+  handle_list starth;
+  handle_list *endh;
+  handle_list freeh[500];
+};
+#endif
+
+struct user_heap_info
+{
+  void *base;
+  void *ptr;
+  void *top;
+  void *max;
+  unsigned chunk;
+};
+
 struct init_cygheap
 {
   _cmalloc_entry *chain;
   char *buckets[32];
-  struct /* User heap stuff. */
-    {
-      void *heapbase;
-      void *heapptr;
-      void *heaptop;
-    };
   cygheap_root root;
   cygheap_user user;
+  user_heap_info user_heap;
   mode_t umask;
   HANDLE shared_h;
   HANDLE console_h;
-  HANDLE etc_changed_h;
   char *cygwin_regname;
   cwdstuff cwd;
   dtable fdtab;
+  const char *shared_prefix;
+#ifdef DEBUGGING
+  cygheap_debug debug;
+#endif
+  struct sigaction *sigs;
 
-  bool etc_changed ();
+  fhandler_tty_slave *ctty;    /* Current tty */
+  fhandler_tty_slave *ctty_on_hold;
+  struct _threadinfo **threadlist;
+  size_t sthreads;
+  int open_fhs;
+  void close_ctty ();
 };
 
-#define CYGHEAPSIZE (sizeof (init_cygheap) + (4000 * sizeof (fhandler_union)) + (2 * 65536))
+#define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + (5 * 65536))
 
 extern init_cygheap *cygheap;
 extern void *cygheap_max;
@@ -203,7 +286,7 @@ class cygheap_fdmanip
   virtual ~cygheap_fdmanip ()
   {
     if (locked)
-      ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdmanip");
+      cygheap->fdtab.unlock ();
   }
   void release ()
   {
@@ -211,6 +294,7 @@ class cygheap_fdmanip
   }
   operator int &() {return fd;}
   operator fhandler_base* &() {return *fh;}
+  operator fhandler_socket* () const {return reinterpret_cast<fhandler_socket *> (*fh);}
   void operator = (fhandler_base *fh) {*this->fh = fh;}
   fhandler_base *operator -> () const {return *fh;}
   bool isopen () const
@@ -228,7 +312,7 @@ class cygheap_fdnew : public cygheap_fdmanip
   cygheap_fdnew (int seed_fd = -1, bool lockit = true)
   {
     if (lockit)
-      SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
+      cygheap->fdtab.lock ();
     if (seed_fd < 0)
       fd = cygheap->fdtab.find_unused_handle ();
     else
@@ -242,7 +326,7 @@ class cygheap_fdnew : public cygheap_fdmanip
       {
        set_errno (EMFILE);
        if (lockit)
-         ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
+         cygheap->fdtab.unlock ();
        locked = false;
       }
   }
@@ -255,7 +339,7 @@ class cygheap_fdget : public cygheap_fdmanip
   cygheap_fdget (int fd, bool lockit = false, bool do_set_errno = true)
   {
     if (lockit)
-      SetResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
+      cygheap->fdtab.lock ();
     if (fd >= 0 && fd < (int) cygheap->fdtab.size
        && *(fh = cygheap->fdtab + fd) != NULL)
       {
@@ -268,7 +352,7 @@ class cygheap_fdget : public cygheap_fdmanip
        if (do_set_errno)
          set_errno (EBADF);
        if (lockit)
-         ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
+         cygheap->fdtab.unlock ();
        locked = false;
       }
   }
@@ -285,5 +369,7 @@ void *__stdcall crealloc (void *, DWORD) __attribute__ ((regparm(2)));
 void *__stdcall ccalloc (cygheap_types, DWORD, DWORD) __attribute__ ((regparm(3)));
 char *__stdcall cstrdup (const char *) __attribute__ ((regparm(1)));
 char *__stdcall cstrdup1 (const char *) __attribute__ ((regparm(1)));
+void __stdcall cfree_and_set (char *&, char * = NULL) __attribute__ ((regparm(2)));
 void __stdcall cygheap_init ();
+extern DWORD _cygheap_start;
 }