OSDN Git Service

* cygtls.h (_threadinfo::call): Remove regparm declaration to work around
[pf3gnuchains/sourceware.git] / winsup / cygwin / cygheap.h
index 7f0f04f..be51527 100644 (file)
@@ -1,6 +1,6 @@
 /* cygheap.h: Cygwin heap manager.
 
-   Copyright 2000, 2001 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,15 +44,14 @@ 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;
 };
 
 /* CGF: FIXME This doesn't belong here */
 
-int path_prefix_p (const char *path1, const char *path2, int len1) __attribute__ ((regparm (3)));
 class cygheap_root
 {
   /* Root directory information.
@@ -86,6 +89,13 @@ public:
   const char *native_path () const { return m->native_path; }
 };
 
+enum homebodies
+{
+  CH_HOMEDRIVE,
+  CH_HOMEPATH,
+  CH_HOME
+};
+
 class cygheap_user
 {
   /* Extendend user information.
@@ -94,41 +104,107 @@ class cygheap_user
   char  *pname;         /* user's name */
   char  *plogsrv;       /* Logon server, may be FQDN */
   char  *pdomain;       /* Logon domain of the user */
-  PSID   psid;          /* buffer for user's SID */
+  char  *homedrive;    /* User's home drive */
+  char  *homepath;     /* User's home path */
+  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:
-  uid_t orig_uid;      /* Remains intact even after impersonation */
-  uid_t orig_gid;      /* Ditto */
-  uid_t real_uid;      /* Remains intact on seteuid, replaced by setuid */
-  gid_t real_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),
-                   psid (NULL), token (INVALID_HANDLE_VALUE) {}
+                   homedrive (NULL), homepath (NULL),
+                   token (INVALID_HANDLE_VALUE) {}
+  */
+
   ~cygheap_user ();
 
+  void init ();
   void set_name (const char *new_name);
   const char *name () const { return pname; }
 
-  void set_logsrv (const char *new_logsrv);
-  const char *logsrv () const { return plogsrv; }
-
-  void set_domain (const char *new_domain);
-  const char *domain () const { return pdomain; }
+  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);
 
-  BOOL set_sid (PSID new_sid);
-  PSID sid () const { return psid; }
-
-  void operator =(cygheap_user &user)
+  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 ()
   {
-    set_name (user.name ());
-    set_logsrv (user.logsrv ());
-    set_domain (user.domain ());
-    set_sid (user.sid ());
+    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.  */
@@ -140,8 +216,8 @@ struct cwdstuff
   char *posix;
   char *win32;
   DWORD hash;
-  muto *lock;
-  char *get (char *buf, int need_posix = 1, int with_chroot = 0, unsigned ulen = MAX_PATH);
+  muto *cwd_lock;
+  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);
@@ -149,29 +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;
@@ -183,11 +282,11 @@ class cygheap_fdmanip
   fhandler_base **fh;
   bool locked;
  public:
-  cygheap_fdmanip () {}
+  cygheap_fdmanip (): fh (NULL) {}
   virtual ~cygheap_fdmanip ()
   {
     if (locked)
-      ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdmanip");
+      cygheap->fdtab.unlock ();
   }
   void release ()
   {
@@ -195,8 +294,16 @@ 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
+  {
+    if (*fh)
+      return true;
+    set_errno (EBADF);
+    return false;
+  }
 };
 
 class cygheap_fdnew : public cygheap_fdmanip
@@ -205,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
@@ -219,10 +326,11 @@ 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;
       }
   }
+  void operator = (fhandler_base *fh) {*this->fh = fh;}
 };
 
 class cygheap_fdget : public cygheap_fdmanip
@@ -231,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)
       {
@@ -244,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;
       }
   }
@@ -253,7 +361,7 @@ class cygheap_fdget : public cygheap_fdmanip
 class child_info;
 void *__stdcall cygheap_setup_for_child (child_info *ci, bool dup_later) __attribute__ ((regparm(2)));
 void __stdcall cygheap_setup_for_child_cleanup (void *, child_info *, bool) __attribute__ ((regparm(3)));
-void __stdcall cygheap_fixup_in_child (child_info *, bool);
+void __stdcall cygheap_fixup_in_child (bool);
 extern "C" {
 void __stdcall cfree (void *) __attribute__ ((regparm(1)));
 void *__stdcall cmalloc (cygheap_types, DWORD) __attribute__ ((regparm(2)));
@@ -261,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;
 }