diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d32bd7b8d..ce3554ef6 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +2008-07-25 Corinna Vinschen + + * dcrt0.cc (dll_crt0_0): Call malloc_init and user_shared_initialize_1 + here in case we're dynamically loaded. Explain why. + (dll_crt0_1): Call user_shared_initialize_1 from here. + * mount.cc (is_native_path): New inline function testing for native + and long Win32 path prefix. + (is_unc_share): Remove long WIn32 path prefix test. + (mount_info::create_root_entry): Use PATH_MAX buffer. + (mount_info::init): Ditto. + (mount_info::add_item): Test for is_native_path as well. + * path.cc (normalize_win32_path): Simplify native path prefix code. + * shared.cc (user_shared_initialize_1): New function taking user + shared initialization code relying on malloc and cygtls. + (user_shared_initialize): Move mountinfo initialization to + user_shared_initialize_1. + * shared_info.h (user_shared_initialize_1): Declare. + * syscalls.cc (seteuid32): Call user_shared_initialize_1 after user + changed. + 2008-07-24 Corinna Vinschen * mount.cc (mount_info::from_fstab): Change system_printf to diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index dddb97f53..5fbf2df05 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -752,6 +752,20 @@ dll_crt0_0 () events_init (); tty_list::init_session (); + if (dynamically_loaded) + { + /* When dynamically loaded. we must initialize the user shared memory + entirely here since dll_crt0_1 will not be called. Stuff in + user_shared_initialize_1 relies on malloc and cygtls being available + and the initialization isn't finished without calling it. In the + non-dynamical case this is called in dll_crt0_1, because malloc_init + has to test for overloaded malloc functionality in the application. + That's not an issue when cygwin is loaded dynamically. It will just + use its own malloc area. */ + malloc_init (); + user_shared_initialize_1 (); + } + debug_printf ("finished dll_crt0_0 initialization"); } @@ -774,6 +788,8 @@ dll_crt0_1 (void *) ProtectHandle (hMainProc); ProtectHandle (hMainThread); + user_shared_initialize_1 (); + cygheap->cwd.init (); /* Initialize pthread mainthread when not forked and it is safe to call new, diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index e754d5661..2f800acad 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -47,13 +47,23 @@ details. */ This function is only used to test for valid input strings. The later normalization drops the native prefixes. */ +static inline bool __stdcall +is_native_path (const char *path) +{ + return isdirsep (path[0]) + && (isdirsep (path[1]) || path[1] == '?') + && (path[2] == '?' || path[2] == '.') + && isdirsep (path[3]) + && isalpha (path[4]); +} + static inline bool __stdcall is_unc_share (const char *path) { const char *p; return (isdirsep (path[0]) && isdirsep (path[1]) - && (isalnum (path[2]) || path[2] == '.' || path[2] == '?') + && isalnum (path[2]) && ((p = strpbrk (path + 3, "\\/")) != NULL) && isalnum (p[1])); } @@ -76,8 +86,8 @@ inline void mount_info::create_root_entry (const PWCHAR root) { /* Create a default root dir from the path the Cygwin DLL is in. */ - char native_root[NT_MAX_PATH]; - sys_wcstombs (native_root, NT_MAX_PATH, root); + char native_root[PATH_MAX]; + sys_wcstombs (native_root, PATH_MAX, root); mount_table->add_item (native_root, "/", MOUNT_SYSTEM | MOUNT_BINARY); /* Create a default cygdrive entry. Note that this is a user entry. This allows to override it with mount, unless the sysadmin created @@ -94,7 +104,7 @@ mount_info::init () { nmounts = 0; PWCHAR pathend; - WCHAR path[NT_MAX_PATH]; + WCHAR path[PATH_MAX]; pathend = wcpcpy (path, cygwin_shared->installation_root); create_root_entry (path); @@ -972,7 +982,7 @@ mount_info::add_item (const char *native, const char *posix, not a UNC or absolute path. */ if (native == NULL || !isabspath (native) || - !(is_unc_share (native) || isdrive (native))) + !(is_native_path (native) || is_unc_share (native) || isdrive (native))) nativeerr = EINVAL; else nativeerr = normalize_win32_path (native, nativetmp, nativetail); diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index ae105491d..4729bc999 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1311,12 +1311,9 @@ normalize_win32_path (const char *src, char *dst, char *&tail) { src += 4; if (src[1] != ':') /* native UNC path */ - { - src += 2; /* Fortunately the first char is not copied... */ - beg_src_slash = true; - } + src += 2; /* Fortunately the first char is not copied... */ else - beg_src_slash = isdirsep (src[0]); + beg_src_slash = false; } if (beg_src_slash && isdirsep (src[1])) { diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index fca79e487..db24e71f1 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -198,6 +198,24 @@ open_shared (const char *name, int n, HANDLE& shared_h, DWORD size, return shared; } +/* User shared initialization which requires malloc and cygtls stuff has to + go here. */ +void +user_shared_initialize_1 () +{ + if (!user_shared->cb) + { + cygpsid sid (cygheap->user.sid ()); + struct passwd *pw = internal_getpwsid (sid); + /* Correct the user name with what's defined in /etc/passwd before + loading the user fstab file. */ + if (pw) + cygheap->user.set_name (pw->pw_name); + user_shared->mountinfo.init (); /* Initialize the mount table. */ + user_shared->cb = sizeof (*user_shared); + } +} + void user_shared_initialize (bool reinit) { @@ -224,19 +242,8 @@ user_shared_initialize (bool reinit) debug_printf ("user shared version %x", user_shared->version); DWORD sversion = (DWORD) InterlockedExchange ((LONG *) &user_shared->version, USER_VERSION_MAGIC); - /* Initialize the Cygwin per-user shared, if necessary */ - if (!sversion) - { - cygpsid sid (cygheap->user.sid ()); - struct passwd *pw = internal_getpwsid (sid); - /* Correct the user name with what's defined in /etc/passwd before - loading the user fstab file. */ - if (pw) - cygheap->user.set_name (pw->pw_name); - user_shared->mountinfo.init (); /* Initialize the mount table. */ - user_shared->cb = sizeof (*user_shared); - } - else + /* Wait for initialization of the Cygwin per-user shared, if necessary */ + if (sversion) { while (!user_shared->cb) low_priority_sleep (0); // Should be hit only very very rarely diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index 684a84a66..d0ef600f9 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -185,3 +185,5 @@ void *__stdcall open_shared (const char *name, int n, HANDLE &shared_h, DWORD si shared_locations&, PSECURITY_ATTRIBUTES psa = &sec_all, DWORD access = FILE_MAP_READ | FILE_MAP_WRITE); extern void user_shared_initialize (bool reinit); +extern void user_shared_initialize_1 (); + diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index f9d030ccc..a5bca574d 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2612,7 +2612,10 @@ seteuid32 (__uid32_t uid) myself->uid = uid; groups.ischanged = FALSE; if (!issamesid) - user_shared_initialize (true); + { + user_shared_initialize (true); + user_shared_initialize_1 (); + } return 0; }