From 41ff9d8c7d4f1224b594eee921b6a966a0585d72 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 7 Sep 2005 03:10:17 +0000 Subject: [PATCH] * dcrt0.cc (initial_env): Don't attempt stracing if dynamically loaded. (dll_crt0_0): Move console initialization earlier. * init.cc (dll_entry): Move console initialization here. * exceptions.cc (init_console_handler): Fully remove any old console handler. * spawn.cc (spawn_guts): Don't fill out windows argv if we've deduced that this is a cygwin-using program. (av::fixup): Always check executables to see if they are using cygwin1.dll. Don't consider .com files to be scripts. * hookapi.cc (rvadelta): New function. (PEHeaderFromHModule): Simplify slightly. (hook_or_detect_cygwin): Use passed in name argument for "HMODULE" rather than incorrectly reading current program. Calculate delta needed to read image data and file names if this isn't a real "HMODULE". --- winsup/cygwin/ChangeLog | 19 +++++++++++++++++++ winsup/cygwin/dcrt0.cc | 3 +-- winsup/cygwin/exceptions.cc | 14 ++++++++++++-- winsup/cygwin/hookapi.cc | 28 ++++++++++++++++++++++------ winsup/cygwin/init.cc | 1 + winsup/cygwin/spawn.cc | 14 +++++++++----- 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d5ffcecf8..36d2bfc1a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,22 @@ +2005-09-06 Christopher Faylor + + * dcrt0.cc (initial_env): Don't attempt stracing if dynamically loaded. + (dll_crt0_0): Move console initialization earlier. + * init.cc (dll_entry): Move console initialization here. + * exceptions.cc (init_console_handler): Fully remove any old console + handler. + + * spawn.cc (spawn_guts): Don't fill out windows argv if we've deduced + that this is a cygwin-using program. + (av::fixup): Always check executables to see if they are using + cygwin1.dll. Don't consider .com files to be scripts. + * hookapi.cc (rvadelta): New function. + (PEHeaderFromHModule): Simplify slightly. + (hook_or_detect_cygwin): Use passed in name argument for "HMODULE" + rather than incorrectly reading current program. Calculate delta + needed to read image data and file names if this isn't a real + "HMODULE". + 2005-09-06 Corinna Vinschen * thread.h: Revert patch from 2005-09-05. diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index e88f64a16..1783d5564 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -547,7 +547,7 @@ initial_env () len = GetModuleFileName (NULL, buf, CYG_MAX_PATH); console_printf ("Sleeping %d, pid %u %s\n", ms, GetCurrentProcessId (), buf); Sleep (ms); - if (!strace.active) + if (!strace.active && !dynamically_loaded) { strace.inited = 0; strace.hello (); @@ -634,7 +634,6 @@ dll_crt0_0 () wincap.init (); initial_env (); - init_console_handler (TRUE); init_global_security (); if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (), GetCurrentProcess (), &hMainProc, 0, FALSE, diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 852b5019f..2f9567e09 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -123,7 +123,8 @@ void init_console_handler (BOOL install_handler) { BOOL res; - SetConsoleCtrlHandler (ctrl_c_handler, FALSE); + while (SetConsoleCtrlHandler (ctrl_c_handler, FALSE)) + continue; if (install_handler) res = SetConsoleCtrlHandler (ctrl_c_handler, TRUE); else if (wincap.has_null_console_handler_routine ()) @@ -591,7 +592,11 @@ int __stdcall handle_sigsuspend (sigset_t tempmask) { if (&_my_tls != _main_tls) - Sleep (INFINITE); + { + cancelable_wait (signal_arrived, INFINITE, cw_cancel_self); + return -1; + } + sigset_t oldmask = myself->getsigmask (); // Remember for restoration set_signal_mask (tempmask, myself->getsigmask ()); @@ -845,6 +850,11 @@ ctrl_c_handler (DWORD type) _my_tls.remove (INFINITE); +#if 0 + if (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT) + proc_subproc (PROC_KILLFORKED, 0); +#endif + /* Return FALSE to prevent an "End task" dialog box from appearing for each Cygwin process window that's open when the computer is shut down or console window is closed. */ diff --git a/winsup/cygwin/hookapi.cc b/winsup/cygwin/hookapi.cc index 97e3330ee..8857b3f0e 100644 --- a/winsup/cygwin/hookapi.cc +++ b/winsup/cygwin/hookapi.cc @@ -23,10 +23,10 @@ struct function_hook static PIMAGE_NT_HEADERS PEHeaderFromHModule (HMODULE hModule) { - PIMAGE_NT_HEADERS pNTHeader = NULL; + PIMAGE_NT_HEADERS pNTHeader; if (PIMAGE_DOS_HEADER(hModule) ->e_magic != IMAGE_DOS_SIGNATURE) - /* nothing */; + pNTHeader = NULL; else { pNTHeader = PIMAGE_NT_HEADERS (PBYTE (hModule) @@ -38,6 +38,18 @@ PEHeaderFromHModule (HMODULE hModule) return pNTHeader; } +long +rvadelta (PIMAGE_NT_HEADERS pnt, long import_rva) +{ + PIMAGE_SECTION_HEADER section = (PIMAGE_SECTION_HEADER) (pnt + 1); + for (int i = 0; i < pnt->FileHeader.NumberOfSections; i++) + if (section[i].VirtualAddress <= import_rva + && (section[i].VirtualAddress + section[i].Misc.VirtualSize) >= import_rva) + // if (strncasematch ((char *) section[i].Name, ".idata", IMAGE_SIZEOF_SHORT_NAME)) + return section[i].VirtualAddress - section[i].PointerToRawData; + return -1; +} + void * putmem (PIMAGE_THUNK_DATA pi, const void *hookfn) { @@ -152,7 +164,7 @@ makename (const char *name, char *&buf, int& i, int inc) void * hook_or_detect_cygwin (const char *name, const void *fn) { - HMODULE hm = GetModuleHandle (NULL); + HMODULE hm = fn ? GetModuleHandle (NULL) : (HMODULE) name; PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule (hm); if (!pExeNTHdr) @@ -163,18 +175,22 @@ hook_or_detect_cygwin (const char *name, const void *fn) if (!importRVA) return false; + long delta = fn ? 0 : rvadelta (pExeNTHdr, importRVA); + if (delta < 0) + return false; + // Convert imports RVA to a usable pointer - PIMAGE_IMPORT_DESCRIPTOR pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA); + PIMAGE_IMPORT_DESCRIPTOR pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA - delta); function_hook fh; fh.origfn = NULL; fh.hookfn = fn; - char *buf = (char *) alloca (strlen (name) + strlen ("64") + sizeof ("_")); + char *buf = fn ? NULL : (char *) alloca (strlen (name) + strlen ("64") + sizeof ("_")); int i; // Iterate through each import descriptor, and redirect if appropriate for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++) { - if (!strcasematch (rva (PSTR, hm, pd->Name), "cygwin1.dll")) + if (!strcasematch (rva (PSTR, hm, pd->Name - delta), "cygwin1.dll")) continue; if (!fn) return (void *) "found it"; // just checking if executable used cygwin1.dll diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc index 491a9d2e3..cad51cc8e 100644 --- a/winsup/cygwin/init.cc +++ b/winsup/cygwin/init.cc @@ -147,6 +147,7 @@ dll_entry (HANDLE h, DWORD reason, void *static_load) case DLL_PROCESS_ATTACH: cygwin_hmodule = (HMODULE) h; dynamically_loaded = (static_load == NULL); + init_console_handler (TRUE); /* Is the stack at an unusual address? This is, an address which is in the usual space occupied by the process image, but below diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index e2c3decf5..87b2b6dcb 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -279,7 +279,7 @@ class av bool win16_exe; bool iscygwin; av (): argv (NULL) {} - av (int ac_in, const char * const *av_in) : calloced (0), error (false), argc (ac_in), win16_exe (false), iscygwin (true) + av (int ac_in, const char * const *av_in) : calloced (0), error (false), argc (ac_in), win16_exe (false), iscygwin (false) { argv = (char **) cmalloc (HEAP_1_ARGV, (argc + 5) * sizeof (char *)); memcpy (argv, av_in, (argc + 1) * sizeof (char *)); @@ -459,6 +459,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, one_line.add (argv[2]); strcpy (real_path, argv[0]); null_app_name = true; + newargv.iscygwin = false; goto skip_arg_parsing; } @@ -476,7 +477,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, if (res) goto out; - if (real_path.iscygexec ()) + if (real_path.iscygexec () || newargv.iscygwin) newargv.dup_all (); else { @@ -1020,9 +1021,7 @@ av::fixup (child_info_types chtype, const char *prog_arg, path_conv& real_path, { /* If the file name ends in either .exe, .com, .bat, or .cmd we assume that it is NOT a script file */ - while (*ext == '\0' || chtype == PROC_SPAWN - || (wincap.detect_win16_exe () && (strcasematch (ext, ".exe") - || strcasematch (ext, ".com")))) + while (1) { HANDLE h = CreateFile (real_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -1092,6 +1091,11 @@ av::fixup (child_info_types chtype, const char *prog_arg, path_conv& real_path, UnmapViewOfFile (buf); if (!pgm) { + if (strcasematch (ext, ".com")) + { + iscygwin = false; + break; + } pgm = (char *) "/bin/sh"; arg1 = NULL; }