diff options
Diffstat (limited to 'winsup/cygwin/cygheap.h')
-rw-r--r-- | winsup/cygwin/cygheap.h | 719 |
1 files changed, 0 insertions, 719 deletions
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h deleted file mode 100644 index 4ed9bfb5a..000000000 --- a/winsup/cygwin/cygheap.h +++ /dev/null @@ -1,719 +0,0 @@ -/* cygheap.h: Cygwin heap manager. - - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - 2011, 2012, 2013, 2014 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include "hires.h" -#include "cygheap_malloc.h" -#include "pwdgrp.h" - -#define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap_max))) - -struct _cmalloc_entry -{ - union - { - unsigned b; - char *ptr; - }; - struct _cmalloc_entry *prev; - char data[0]; -}; - -struct cygheap_root_mount_info -{ - char posix_path[CYG_MAX_PATH]; - unsigned posix_pathlen; - char native_path[CYG_MAX_PATH]; - unsigned native_pathlen; - bool caseinsensitive; -}; - -/* CGF: FIXME This doesn't belong here */ - -class cygheap_root -{ - /* Root directory information. - This is used after a chroot is called. */ - struct cygheap_root_mount_info *m; - -public: - bool posix_ok (const char *path) - { - if (!m) - return 1; - return path_prefix_p (m->posix_path, path, m->posix_pathlen, - m->caseinsensitive); - } - bool ischroot_native (const char *path) - { - if (!m) - return 1; - return strncasematch (m->native_path, path, m->native_pathlen) - && (path[m->native_pathlen] == '\\' || !path[m->native_pathlen]); - } - const char *unchroot (const char *path) - { - if (!m) - return path; - const char *p = path + m->posix_pathlen; - if (!*p) - p = "/"; - return p; - } - bool exists () {return !!m;} - void set (const char *, const char *, bool); - size_t posix_length () const { return m->posix_pathlen; } - const char *posix_path () const { return m->posix_path; } - size_t native_length () const { return m->native_pathlen; } - const char *native_path () const { return m->native_path; } -}; - -enum homebodies -{ - CH_HOMEDRIVE, - CH_HOMEPATH, - CH_HOME -}; - -class cygheap_user -{ - /* Extendend user information. - The information is derived from the internal_getlogin call - when on a NT system. */ - char *pname; /* user's name */ - char *plogsrv; /* Logon server, may be FQDN */ - char *pdomain; /* Logon domain of the user */ - char *homedrive; /* User's home drive */ - char *homepath; /* User's home path */ - char *psystemroot; /* Value of SYSTEMROOT */ - 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 saved_uid; /* Remains intact even after impersonation */ - gid_t saved_gid; /* Ditto */ - uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */ - gid_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 external_token; - HANDLE internal_token; - HANDLE curr_primary_token; - HANDLE curr_imp_token; - bool ext_token_is_restricted; /* external_token is restricted token */ - bool curr_token_is_restricted; /* curr_primary_token is restricted token */ - bool setuid_to_restricted; /* switch to restricted token by setuid () */ - - /* 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), - 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 *, 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 *env_systemroot (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; - } - void set_sid (PSID new_sid) { effec_cygsid = new_sid;} - void set_saved_sid () { saved_cygsid = effec_cygsid; } - cygpsid &sid () { return effec_cygsid; } - cygpsid &saved_sid () { return saved_cygsid; } - const char *ontherange (homebodies what, struct passwd * = NULL); -#define NO_IMPERSONATION NULL - bool issetuid () const { return curr_imp_token != NO_IMPERSONATION; } - HANDLE primary_token () { return curr_primary_token; } - HANDLE imp_token () { return curr_imp_token; } - void deimpersonate () - { - RevertToSelf (); - } - bool reimpersonate () - { - if (issetuid ()) - return ImpersonateLoggedOnUser (primary_token ()); - return true; - } - bool has_impersonation_tokens () - { return external_token != NO_IMPERSONATION - || internal_token != NO_IMPERSONATION - || curr_primary_token != NO_IMPERSONATION; } - void close_impersonation_tokens () - { - if (curr_imp_token != NO_IMPERSONATION) - CloseHandle (curr_imp_token); - if (curr_primary_token != NO_IMPERSONATION - && curr_primary_token != external_token - && curr_primary_token != internal_token) - CloseHandle (curr_primary_token); - if (external_token != NO_IMPERSONATION) - CloseHandle (external_token); - if (internal_token != NO_IMPERSONATION) - CloseHandle (internal_token); - } - PWCHAR get_windows_id (PWCHAR buf) - { - return effec_cygsid.string (buf); - } - char *get_windows_id (char *buf) - { - return effec_cygsid.string (buf); - } - - const char __reg3 *test_uid (char *&, const char *, size_t); -}; - -/* cwd cache stuff. */ - -enum fcwd_version_t { - FCWD_OLD, - FCWD_W7, - FCWD_W8 -}; - -/* This class is used to store the CWD starting with Windows Vista. - The CWD storage in the RTL_USER_PROCESS_PARAMETERS block is only - an afterthought now. The actual CWD storage is a FAST_CWD structure - which is allocated on the process heap. The new method only requires - minimal locking and it's much more multi-thread friendly. Presumably - it minimizes contention when accessing the CWD. - The class fcwd_access_t is supposed to encapsulate the gory implementation - details depending on OS version from the calling functions. - The layout of all structures has been tested on 32 and 64 bit. */ -class fcwd_access_t { - /* This is the layout used in Windows 8. */ - struct FAST_CWD_8 { - LONG ReferenceCount; /* Only release when this is 0. */ - HANDLE DirectoryHandle; - ULONG OldDismountCount; /* Reflects the system DismountCount - at the time the CWD has been set. */ - UNICODE_STRING Path; /* Path's Buffer member always refers - to the following Buffer array. */ - LONG FSCharacteristics; /* Taken from FileFsDeviceInformation */ - WCHAR Buffer[MAX_PATH] __attribute ((aligned (8))); - }; - /* This is the layout used in Windows 7 and Vista. */ - struct FAST_CWD_7 { - UNICODE_STRING Path; /* Path's Buffer member always refers - to the following Buffer array. */ - HANDLE DirectoryHandle; - LONG FSCharacteristics; /* Taken from FileFsDeviceInformation */ - LONG ReferenceCount; /* Only release when this is 0. */ - ULONG OldDismountCount; /* Reflects the system DismountCount - at the time the CWD has been set. */ - WCHAR Buffer[MAX_PATH] __attribute ((aligned (8))); - }; - /* This is the old FAST_CWD structure up to the patch from KB 2393802, - release in February 2011. */ - struct FAST_CWD_OLD { - LONG ReferenceCount; /* Only release when this is 0. */ - HANDLE DirectoryHandle; - ULONG OldDismountCount; /* Reflects the system DismountCount - at the time the CWD has been set. */ - UNICODE_STRING Path; /* Path's Buffer member always refers - to the following Buffer array. */ - WCHAR Buffer[MAX_PATH]; - }; - union { - FAST_CWD_OLD fold; - FAST_CWD_7 f7; - FAST_CWD_8 f8; - }; - -#define IMPLEMENT(type, name) \ - type name () { \ - switch (fast_cwd_version ()) { \ - case FCWD_OLD: \ - default: \ - return fold.name; \ - case FCWD_W7: \ - return f7.name; \ - case FCWD_W8: \ - return f8.name; \ - } \ - } - IMPLEMENT (LONG &, ReferenceCount) - IMPLEMENT (HANDLE &, DirectoryHandle) - IMPLEMENT (ULONG &, OldDismountCount) - IMPLEMENT (UNICODE_STRING &, Path) - IMPLEMENT (WCHAR *, Buffer) - void SetFSCharacteristics (LONG val); - static fcwd_version_t &fast_cwd_version (void); - -public: - void CopyPath (UNICODE_STRING &target); - void Free (PVOID heap); - void FillIn (HANDLE dir, PUNICODE_STRING name, ULONG old_dismount_count); - static void SetDirHandleFromBufferPointer (PWCHAR buf_p, HANDLE dir); - static void SetVersionFromPointer (PBYTE buf_p, bool is_buffer); -}; - -class cwdstuff -{ -private: - char *posix; - HANDLE dir; - DWORD drive_length; - int error; /* This contains an errno number which corresponds - to the problem with this path when trying to start - a native Win32 application. See cwdstuff::set for - how it gets set. See child_info_spawn::worker for how - it's evaluated. */ - - friend class fcwd_access_t; - /* fast_cwd_ptr is a pointer to the global RtlpCurDirRef pointer in - ntdll.dll pointing to the FAST_CWD structure which constitutes the CWD. - Unfortunately RtlpCurDirRef is not exported from ntdll.dll. */ - fcwd_access_t **fast_cwd_ptr; - /* Type of FAST_CWD used on this system. Keeping this information - available in shared memory avoids to test for the version every time - around. Default to new version. */ - fcwd_version_t fast_cwd_version; - void override_win32_cwd (bool init, ULONG old_dismount_count); - -public: - UNICODE_STRING win32; - static muto cwd_lock; - const char *get_posix () const { return posix; }; - void reset_posix (wchar_t *w_cwd); - char *get (char *buf, int need_posix = 1, int with_chroot = 0, - unsigned ulen = NT_MAX_PATH); - PWCHAR get (PWCHAR buf, unsigned buflen = NT_MAX_PATH) - { - cwd_lock.acquire (); - buf[0] = L'\0'; - wcsncat (buf, win32.Buffer, buflen - 1); - cwd_lock.release (); - return buf; - } - HANDLE get_handle () { return dir; } - DWORD get_drive (char * dst) - { - cwd_lock.acquire (); - DWORD ret = sys_wcstombs (dst, NT_MAX_PATH, win32.Buffer, drive_length); - cwd_lock.release (); - return ret; - } - int get_error () const { return error; } - const char *get_error_desc () const; - void init (); - int set (path_conv *, const char *); -}; - -#ifdef DEBUGGING -struct cygheap_debug -{ - handle_list starth; - handle_list freeh[500]; -}; -#endif - -struct cygheap_locale -{ - mbtowc_p mbtowc; - wctomb_p wctomb; - char charset[ENCODING_LEN + 1]; -}; - -struct user_heap_info -{ - void *base; - void *ptr; - void *top; - void *max; - SIZE_T chunk; - void __reg2 *sbrk (ptrdiff_t); - void __reg1 init (); -}; - -class cygheap_domain_info -{ - PWCHAR pdom_name; - PWCHAR pdom_dns_name; - cygsid pdom_sid; - - PWCHAR adom_name; - cygsid adom_sid; - - PDS_DOMAIN_TRUSTSW tdom; - ULONG tdom_count; - - PWCHAR rfc2307_domain_buf; - -public: - bool init (); - - inline PCWSTR primary_flat_name () const { return pdom_name; } - inline PCWSTR primary_dns_name () const { return pdom_dns_name; } - inline cygsid &primary_sid () { return pdom_sid; } - - inline bool member_machine () const { return pdom_sid != NO_SID; } - - inline PCWSTR account_flat_name () const { return adom_name; } - inline cygsid &account_sid () { return adom_sid; } - - inline PDS_DOMAIN_TRUSTSW trusted_domain (ULONG idx) const - { return (idx < tdom_count) ? tdom + idx : NULL; } - - inline PWCHAR get_rfc2307_domain () const - { return rfc2307_domain_buf ?: NULL; } -}; - -class cygheap_pwdgrp -{ - enum nss_pfx_t { - NSS_PFX_AUTO = 0, - NSS_PFX_PRIMARY, - NSS_PFX_ALWAYS - }; -public: - enum nss_scheme_method { - NSS_SCHEME_FALLBACK = 0, - NSS_SCHEME_WINDOWS, - NSS_SCHEME_CYGWIN, - NSS_SCHEME_UNIX, - NSS_SCHEME_DESC, - NSS_SCHEME_PATH, - NSS_SCHEME_FREEATTR - }; - struct nss_scheme_t { - nss_scheme_method method; - PWCHAR attrib; - }; -private: - bool nss_inited; - uint32_t pwd_src; - uint32_t grp_src; - nss_pfx_t prefix; - WCHAR separator[2]; - bool caching; - -#define NSS_SCHEME_MAX 4 - nss_scheme_t home_scheme[NSS_SCHEME_MAX]; - nss_scheme_t shell_scheme[NSS_SCHEME_MAX]; - nss_scheme_t gecos_scheme[NSS_SCHEME_MAX]; - - uint32_t enums; - PWCHAR enum_tdoms; - - void nss_init_line (const char *line); - void _nss_init (); - -public: - struct { - pwdgrp cygserver; - pwdgrp file; - pwdgrp win; - } pwd_cache; - struct { - pwdgrp cygserver; - pwdgrp file; - pwdgrp win; - } grp_cache; - - void init (); - - /* Implemented in ldap.cc */ - PWCHAR *ldap_user_attr; - void init_ldap_user_attr (); - - inline void nss_init () { if (!nss_inited) _nss_init (); } - inline bool nss_pwd_files () const { return !!(pwd_src & NSS_SRC_FILES); } - inline bool nss_pwd_db () const { return !!(pwd_src & NSS_SRC_DB); } - inline int nss_pwd_src () const { return pwd_src; } /* CW_GETNSS_PWD_SRC */ - inline bool nss_grp_files () const { return !!(grp_src & NSS_SRC_FILES); } - inline bool nss_grp_db () const { return !!(grp_src & NSS_SRC_DB); } - inline int nss_grp_src () const { return grp_src; } /* CW_GETNSS_GRP_SRC */ - inline bool nss_prefix_auto () const { return prefix == NSS_PFX_AUTO; } - inline bool nss_prefix_primary () const { return prefix == NSS_PFX_PRIMARY; } - inline bool nss_prefix_always () const { return prefix == NSS_PFX_ALWAYS; } - inline PCWSTR nss_separator () const { return separator; } - inline bool nss_cygserver_caching () const { return caching; } - inline void nss_disable_cygserver_caching () { caching = false; } - - char *get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR name, - bool fq); - char *get_home (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom, - PCWSTR name, bool fq); - - char *get_shell (cyg_ldap *pldap, PCWSTR dom, PCWSTR name, bool fq); - char *get_shell (struct _USER_INFO_3 *ui, PCWSTR dom, PCWSTR name, bool fq); - - char *get_gecos (cyg_ldap *pldap, PCWSTR dom, PCWSTR name, bool fq); - char *get_gecos (struct _USER_INFO_3 *ui, PCWSTR dom, PCWSTR name, bool fq); - - inline int nss_db_enums () const { return enums; } - inline PCWSTR nss_db_enum_tdoms () const { return enum_tdoms; } -}; - -class cygheap_ugid_cache -{ - struct idmap { - uint32_t nfs_id; - uint32_t cyg_id; - }; - class idmaps { - uint32_t _cnt; - uint32_t _max; - idmap *_map; - public: - uint32_t get (uint32_t id) const - { - for (uint32_t i = 0; i < _cnt; ++i) - if (_map[i].nfs_id == id) - return _map[i].cyg_id; - return (uint32_t) -1; - } - void add (uint32_t nfs_id, uint32_t cyg_id) - { - if (_cnt >= _max) - _map = (idmap *) crealloc (_map, (_max += 10) * sizeof (*_map)); - _map[_cnt].nfs_id = nfs_id; - _map[_cnt].cyg_id = cyg_id; - ++_cnt; - } - }; - idmaps uids; - idmaps gids; - -public: - uid_t get_uid (uid_t uid) const { return uids.get (uid); } - gid_t get_gid (gid_t gid) const { return gids.get (gid); } - void add_uid (uid_t nfs_uid, uid_t cyg_uid) { uids.add (nfs_uid, cyg_uid); } - void add_gid (gid_t nfs_gid, gid_t cyg_gid) { gids.add (nfs_gid, cyg_gid); } -}; - -struct hook_chain -{ - void **loc; - const void *func; - struct hook_chain *next; -}; - -struct mini_cygheap -{ - cygheap_locale locale; -}; - -#define NBUCKETS 40 - -struct threadlist_t -{ - struct _cygtls *thread; - HANDLE mutex; /* Used to avoid accessing tls area of - deleted thread. See comment in - cygheap::remove_tls for a description. */ -}; - -struct init_cygheap: public mini_cygheap -{ - _cmalloc_entry *chain; - unsigned bucket_val[NBUCKETS]; - char *buckets[NBUCKETS]; - WCHAR installation_root[PATH_MAX]; - WCHAR installation_dir[PATH_MAX]; - size_t installation_dir_len; - UNICODE_STRING installation_key; - WCHAR installation_key_buf[18]; - cygheap_root root; - cygheap_domain_info dom; - cygheap_pwdgrp pg; - cygheap_ugid_cache ugid_cache; - cygheap_user user; - user_heap_info user_heap; - mode_t umask; - unsigned long rlim_core; - HANDLE console_h; - cwdstuff cwd; - dtable fdtab; -#ifdef DEBUGGING - cygheap_debug debug; -#endif - struct sigaction *sigs; - - fhandler_termios *ctty; /* Current tty */ - threadlist_t *threadlist; - uint32_t sthreads; - pid_t pid; /* my pid */ - struct { /* Equivalent to using LIST_HEAD. */ - struct inode_t *lh_first; - } inode_list; /* Global inode pointer for adv. locking. */ - hook_chain hooks; - void close_ctty (); - void init_installation_root (); - void __reg1 init_tls_list ();; - void __reg2 add_tls (_cygtls *); - HANDLE __reg3 remove_tls (_cygtls *); - threadlist_t __reg2 *find_tls (_cygtls *); - threadlist_t __reg3 *find_tls (int, bool&); - void unlock_tls (threadlist_t *t) { if (t) ReleaseMutex (t->mutex); } -}; - - -#define _CYGHEAPSIZE_SLOP (128 * 1024) -#define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + _CYGHEAPSIZE_SLOP) -#define CYGHEAPSIZE_MIN (sizeof (init_cygheap) + (10000 * sizeof (fhandler_union))) - -extern init_cygheap *cygheap; -extern void *cygheap_max; - -class cygheap_fdmanip -{ - protected: - int fd; - bool locked; - public: - cygheap_fdmanip (): fd (-1), locked (false) {} - virtual ~cygheap_fdmanip () - { - if (locked) - cygheap->fdtab.unlock (); - } - virtual void release () { cygheap->fdtab.release (fd); } - operator int &() {return fd;} - operator fhandler_base* &() {return cygheap->fdtab[fd];} - operator fhandler_socket* () const {return reinterpret_cast<fhandler_socket *> (cygheap->fdtab[fd]);} - operator fhandler_pipe* () const {return reinterpret_cast<fhandler_pipe *> (cygheap->fdtab[fd]);} - void operator = (fhandler_base *fh) {cygheap->fdtab[fd] = fh;} - fhandler_base *operator -> () const {return cygheap->fdtab[fd];} - bool isopen () const - { - if (cygheap->fdtab[fd]) - return true; - set_errno (EBADF); - return false; - } -}; - -class cygheap_fdnew : public cygheap_fdmanip -{ - public: - cygheap_fdnew (int seed_fd = -1, bool lockit = true) - { - if (lockit) - cygheap->fdtab.lock (); - if (seed_fd < 0) - fd = cygheap->fdtab.find_unused_handle (); - else - fd = cygheap->fdtab.find_unused_handle (seed_fd + 1); - if (fd >= 0) - locked = lockit; - else - { - /* errno set by find_unused_handle */ - if (lockit) - cygheap->fdtab.unlock (); - locked = false; - } - } - ~cygheap_fdnew () - { - if (cygheap->fdtab[fd]) - cygheap->fdtab[fd]->inc_refcnt (); - } - void operator = (fhandler_base *fh) {cygheap->fdtab[fd] = fh;} -}; - -class cygheap_fdget : public cygheap_fdmanip -{ - fhandler_base *fh; -public: - cygheap_fdget (int fd, bool lockit = false, bool do_set_errno = true) - { - if (lockit) - cygheap->fdtab.lock (); - if (fd >= 0 && fd < (int) cygheap->fdtab.size && cygheap->fdtab[fd] != NULL) - { - this->fd = fd; - locked = lockit; - fh = cygheap->fdtab[fd]; - fh->inc_refcnt (); - } - else - { - this->fd = -1; - if (do_set_errno) - set_errno (EBADF); - if (lockit) - cygheap->fdtab.unlock (); - locked = false; - fh = NULL; - } - } - ~cygheap_fdget () - { - if (fh && fh->dec_refcnt () <= 0) - { - debug_only_printf ("deleting fh %p", fh); - delete fh; - } - } - void release () { cygheap->fdtab.release (fd); } -}; - -class cygheap_fdenum : public cygheap_fdmanip -{ - public: - cygheap_fdenum (bool lockit = false) - { - locked = lockit; - if (lockit) - cygheap->fdtab.lock (); - fd = -1; - } - int next () - { - while (++fd < (int) cygheap->fdtab.size) - if (cygheap->fdtab[fd] != NULL) - return fd; - return -1; - } - void rewind () - { - fd = -1; - } -}; - -void __stdcall cygheap_fixup_in_child (bool); -void __stdcall cygheap_init (); -void setup_cygheap (); -extern char _cygheap_start[] __attribute__((section(".idata"))); |