diff options
author | cvs2svn <> | 2002-09-22 16:04:17 +0400 |
---|---|---|
committer | cvs2svn <> | 2002-09-22 16:04:17 +0400 |
commit | e8038acb1b5f441fe7b2570c9448cf73b2038477 (patch) | |
tree | 9bc675d4928360fc4998eb5a43727fd1a4ce427d /winsup/cygwin/exceptions.cc | |
parent | 9783ce28caf426c5ab39d1d6aefa31cfdb1b8234 (diff) |
This commit was manufactured by cvs2svn to create tagZ-cygwin_daemon_merge_HEAD
'Z-cygwin_daemon_merge_HEAD'.
Sprout from cygwin_daemon 2002-01-02 00:06:36 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.'
Cherrypick from cygwin_daemon 2002-02-25 17:47:52 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/how-spawn-works.txt
winsup/cygwin/wsock_event.h
Cherrypick from cygwin_daemon 2002-06-06 15:35:10 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/include/netinet/udp.h
winsup/cygwin/stackdump.sgml
Cherrypick from cygwin_daemon 2002-01-17 10:39:38 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/libc/fnmatch.c
Cherrypick from cygwin_daemon 2002-07-03 20:31:40 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/include/sys/statfs.h
Cherrypick from cygwin_daemon 2002-09-04 15:17:25 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin_daemon'.':
winsup/cygwin/how-autoload-works.txt
Cherrypick from master 2002-09-22 12:04:15 UTC Conrad Scott <conrad.scott@dsl.pipex.com> '2002-09-22 Conrad Scott <conrad.scott@dsl.pipex.com>':
winsup/cygserver/threaded_queue.cc
winsup/cygserver/woutsup.h
winsup/cygwin/CYGWIN_LICENSE
winsup/cygwin/ChangeLog
winsup/cygwin/ChangeLog-1998
winsup/cygwin/ChangeLog-1999
winsup/cygwin/ChangeLog-2000
winsup/cygwin/Makefile.in
winsup/cygwin/assert.cc
winsup/cygwin/autoload.cc
winsup/cygwin/child_info.h
winsup/cygwin/configure
winsup/cygwin/configure.in
winsup/cygwin/cygerrno.h
winsup/cygwin/cygheap.cc
winsup/cygwin/cygheap.h
winsup/cygwin/cygmagic
winsup/cygwin/cygmalloc.h
winsup/cygwin/cygrun.c
winsup/cygwin/cygserver.cc
winsup/cygwin/cygserver_client.cc
winsup/cygwin/cygserver_ipc.h
winsup/cygwin/cygserver_process.cc
winsup/cygwin/cygserver_shm.cc
winsup/cygwin/cygserver_shm.h
winsup/cygwin/cygserver_transport.cc
winsup/cygwin/cygserver_transport_pipes.cc
winsup/cygwin/cygserver_transport_sockets.cc
winsup/cygwin/cygthread.cc
winsup/cygwin/cygthread.h
winsup/cygwin/cygwin.din
winsup/cygwin/cygwin.sc
winsup/cygwin/dcrt0.cc
winsup/cygwin/debug.cc
winsup/cygwin/debug.h
winsup/cygwin/dir.cc
winsup/cygwin/dlfcn.cc
winsup/cygwin/dll_init.cc
winsup/cygwin/dll_init.h
winsup/cygwin/dlmalloc.c
winsup/cygwin/dtable.cc
winsup/cygwin/dtable.h
winsup/cygwin/environ.cc
winsup/cygwin/environ.h
winsup/cygwin/errno.cc
winsup/cygwin/exceptions.cc
winsup/cygwin/exec.cc
winsup/cygwin/external.cc
winsup/cygwin/fcntl.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_clipboard.cc
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_disk_file.cc
winsup/cygwin/fhandler_dsp.cc
winsup/cygwin/fhandler_floppy.cc
winsup/cygwin/fhandler_mem.cc
winsup/cygwin/fhandler_proc.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/fhandler_random.cc
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/fhandler_registry.cc
winsup/cygwin/fhandler_serial.cc
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/fhandler_virtual.cc
winsup/cygwin/fhandler_windows.cc
winsup/cygwin/fhandler_zero.cc
winsup/cygwin/fork.cc
winsup/cygwin/glob.c
winsup/cygwin/gmon.c
winsup/cygwin/grp.cc
winsup/cygwin/heap.cc
winsup/cygwin/heap.h
winsup/cygwin/hires.h
winsup/cygwin/how-cygheap-works.txt
winsup/cygwin/how-fhandlers-work.txt
winsup/cygwin/how-signals-work.txt
winsup/cygwin/how-to-debug-cygwin.txt
winsup/cygwin/include/cygwin/acl.h
winsup/cygwin/include/cygwin/cygserver.h
winsup/cygwin/include/cygwin/cygserver_process.h
winsup/cygwin/include/cygwin/cygserver_transport.h
winsup/cygwin/include/cygwin/cygserver_transport_pipes.h
winsup/cygwin/include/cygwin/cygserver_transport_sockets.h
winsup/cygwin/include/cygwin/grp.h
winsup/cygwin/include/cygwin/if.h
winsup/cygwin/include/cygwin/ipc.h
winsup/cygwin/include/cygwin/msg.h
winsup/cygwin/include/cygwin/mtio.h
winsup/cygwin/include/cygwin/sem.h
winsup/cygwin/include/cygwin/shm.h
winsup/cygwin/include/cygwin/socket.h
winsup/cygwin/include/cygwin/stat.h
winsup/cygwin/include/cygwin/types.h
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/fnmatch.h
winsup/cygwin/include/getopt.h
winsup/cygwin/include/glob.h
winsup/cygwin/include/limits.h
winsup/cygwin/include/netdb.h
winsup/cygwin/include/netinet/ip.h
winsup/cygwin/include/netinet/tcp.h
winsup/cygwin/include/pthread.h
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/include/sys/ioctl.h
winsup/cygwin/include/sys/mount.h
winsup/cygwin/include/sys/resource.h
winsup/cygwin/include/sys/socket.h
winsup/cygwin/include/sys/soundcard.h
winsup/cygwin/include/sys/strace.h
winsup/cygwin/include/sys/sysmacros.h
winsup/cygwin/include/sys/termios.h
winsup/cygwin/include/sys/uio.h
winsup/cygwin/include/sys/un.h
winsup/cygwin/include/sys/vfs.h
winsup/cygwin/init.cc
winsup/cygwin/ioctl.cc
winsup/cygwin/ipc.cc
winsup/cygwin/lib/cygwin_crt0.c
winsup/cygwin/lib/dll_main.cc
winsup/cygwin/lib/getopt.c
winsup/cygwin/localtime.cc
winsup/cygwin/malloc.cc
winsup/cygwin/malloc_wrapper.cc
winsup/cygwin/miscfuncs.cc
winsup/cygwin/mkvers.sh
winsup/cygwin/mmap.cc
winsup/cygwin/msg.cc
winsup/cygwin/net.cc
winsup/cygwin/ntdll.h
winsup/cygwin/ntea.cc
winsup/cygwin/passwd.cc
winsup/cygwin/path.cc
winsup/cygwin/path.h
winsup/cygwin/perthread.h
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h
winsup/cygwin/pipe.cc
winsup/cygwin/poll.cc
winsup/cygwin/pthread.cc
winsup/cygwin/pwdgrp.h
winsup/cygwin/regex/regcomp.c
winsup/cygwin/registry.cc
winsup/cygwin/resource.cc
winsup/cygwin/safe_memory.h
winsup/cygwin/sched.cc
winsup/cygwin/sec_acl.cc
winsup/cygwin/sec_helper.cc
winsup/cygwin/security.cc
winsup/cygwin/security.h
winsup/cygwin/select.cc
winsup/cygwin/sem.cc
winsup/cygwin/shared.cc
winsup/cygwin/shared_info.h
winsup/cygwin/shm.cc
winsup/cygwin/signal.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/sigproc.h
winsup/cygwin/smallprint.c
winsup/cygwin/spawn.cc
winsup/cygwin/speclib
winsup/cygwin/strace.cc
winsup/cygwin/sync.cc
winsup/cygwin/sync.h
winsup/cygwin/syscalls.cc
winsup/cygwin/sysconf.cc
winsup/cygwin/syslog.cc
winsup/cygwin/termios.cc
winsup/cygwin/thread.cc
winsup/cygwin/thread.h
winsup/cygwin/threaded_queue.cc
winsup/cygwin/threaded_queue.h
winsup/cygwin/times.cc
winsup/cygwin/tty.cc
winsup/cygwin/tty.h
winsup/cygwin/uinfo.cc
winsup/cygwin/uname.cc
winsup/cygwin/wait.cc
winsup/cygwin/winbase.h
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h
winsup/cygwin/window.cc
winsup/cygwin/winsup.h
winsup/cygwin/winver.rc
winsup/cygwin/woutsup.h
Delete:
winsup/cygwin/include/cygwin/ip.h
winsup/cygwin/include/sys/ipc.h
winsup/cygwin/include/sys/shm.h
winsup/cygwin/include/wchar.h
winsup/cygwin/lib/_cygwin_S_IEXEC.cc
winsup/cygwin/regexp/regerror.c
winsup/cygwin/regexp/regexp.3
winsup/cygwin/regexp/regexp.c
winsup/cygwin/regexp/regsub.c
winsup/cygwin/shortcut.c
winsup/cygwin/shortcut.h
winsup/cygwin/test.c
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r-- | winsup/cygwin/exceptions.cc | 125 |
1 files changed, 73 insertions, 52 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 0102371a7..a1d7019fe 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1,6 +1,6 @@ /* exceptions.cc - Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. This file is part of Cygwin. @@ -11,6 +11,7 @@ details. */ #include "winsup.h" #include <imagehlp.h> #include <errno.h> +#include <stdlib.h> #include "exceptions.h" #include "sync.h" @@ -37,6 +38,9 @@ extern DWORD __no_sig_start, __no_sig_end; extern DWORD sigtid; +extern HANDLE hExeced; +extern DWORD dwExeced; + static BOOL WINAPI ctrl_c_handler (DWORD); static void signal_exit (int) __attribute__ ((noreturn)); static char windows_system_directory[1024]; @@ -49,11 +53,11 @@ static NO_COPY muto *mask_sync = NULL; HMODULE NO_COPY cygwin_hmodule; -static const struct +NO_COPY static struct { unsigned int code; const char *name; -} status_info[] NO_COPY = +} status_info[] = { #define X(s) s, #s { X (STATUS_ABANDONED_WAIT_0) }, @@ -112,8 +116,12 @@ init_exception_handler (exception_list *el) #endif void -set_console_handler () +early_stuff_init () { + (void) SetConsoleCtrlHandler (ctrl_c_handler, FALSE); + if (!SetConsoleCtrlHandler (ctrl_c_handler, TRUE)) + system_printf ("SetConsoleCtrlHandler failed, %E"); + /* Initialize global security attribute stuff */ sec_none.nLength = sec_none_nih.nLength = @@ -123,10 +131,6 @@ set_console_handler () sec_none.lpSecurityDescriptor = sec_none_nih.lpSecurityDescriptor = NULL; sec_all.lpSecurityDescriptor = sec_all_nih.lpSecurityDescriptor = get_null_sd (); - - (void) SetConsoleCtrlHandler (ctrl_c_handler, FALSE); - if (!SetConsoleCtrlHandler (ctrl_c_handler, TRUE)) - system_printf ("SetConsoleCtrlHandler failed, %E"); } extern "C" void @@ -144,11 +148,13 @@ error_start_init (const char *buf) return; } - char myself_posix_name[MAX_PATH]; + char pgm[MAX_PATH + 1]; + if (!GetModuleFileName (NULL, pgm, MAX_PATH)) + strcpy (pgm, "cygwin1.dll"); + for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\')) + *p = '/'; - /* FIXME: gdb cannot use win32 paths, but what if debugger isn't gdb? */ - cygwin_conv_to_posix_path (myself->progname, myself_posix_name); - __small_sprintf (debugger_command, "%s %s", buf, myself_posix_name); + __small_sprintf (debugger_command, "%s %s", buf, pgm); } static void @@ -170,7 +176,10 @@ open_stackdumpfile () CREATE_ALWAYS, 0, 0); if (h != INVALID_HANDLE_VALUE) { - system_printf ("Dumping stack trace to %s", corefile); + if (!myself->ppid_handle) + system_printf ("Dumping stack trace to %s", corefile); + else + debug_printf ("Dumping stack trace to %s", corefile); SetStdHandle (STD_ERROR_HANDLE, h); } } @@ -334,8 +343,6 @@ try_to_debug (bool waitloop) __small_sprintf (strchr (debugger_command, '\0'), " %u", GetCurrentProcessId ()); - BOOL dbg; - SetThreadPriority (hMainThread, THREAD_PRIORITY_HIGHEST); PROCESS_INFORMATION pi = {NULL, 0, 0, 0}; @@ -368,6 +375,7 @@ try_to_debug (bool waitloop) } } + BOOL dbg; dbg = CreateProcess (NULL, debugger_command, NULL, @@ -379,19 +387,19 @@ try_to_debug (bool waitloop) &si, &pi); - static int NO_COPY keep_looping = 0; - - if (dbg) + if (!dbg) + system_printf ("Failed to start debugger: %E"); + else { + SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE); if (!waitloop) return 1; - SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE); - while (keep_looping) + while (!being_debugged ()) /* spin */; + Sleep (4000); + small_printf ("*** continuing from debugger call\n"); } - - system_printf ("Failed to start debugger: %E"); /* FIXME: need to know handles of all running threads to resume_all_threads_except (current_thread_id); */ @@ -593,6 +601,7 @@ sig_handle_tty_stop (int sig) myself->process_state &= ~PID_STOPPED; return; } + myself->stopsig = sig; /* See if we have a living parent. If so, send it a special signal. * It will figure out exactly which pid has stopped by scanning @@ -601,11 +610,14 @@ sig_handle_tty_stop (int sig) if (my_parent_is_alive ()) { pinfo parent (myself->ppid); - sig_send (parent, SIGCHLD); + if (!(parent->getsig (SIGCHLD).sa_flags & SA_NOCLDSTOP)) + sig_send (parent, SIGCHLD); } sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p", myself->pid, sig, myself->ppid_handle); - SuspendThread (hMainThread); + if (WaitForSingleObject (sigCONT, INFINITE) != WAIT_OBJECT_0) + api_fatal ("WaitSingleObject failed, %E"); + (void) ResetEvent (sigCONT); return; } } @@ -676,7 +688,8 @@ interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack, sigsave.retaddr = retaddr; sigsave.retaddr_on_stack = retaddr_on_stack; /* FIXME: Not multi-thread aware */ - sigsave.newmask = myself->getsigmask () | siga.sa_mask | SIGTOMASK (sig); + sigsave.oldmask = myself->getsigmask (); + sigsave.newmask = sigsave.oldmask | siga.sa_mask | SIGTOMASK (sig); sigsave.sa_flags = siga.sa_flags; sigsave.func = (void (*)(int)) handler; sigsave.sig = sig; @@ -705,15 +718,16 @@ interrupt_now (CONTEXT *ctx, int sig, void *handler, struct sigaction& siga) void __stdcall signal_fixup_after_fork () { - if (!sigsave.sig) - return; - - sigsave.sig = 0; - if (sigsave.retaddr_on_stack) + if (sigsave.sig) { - *sigsave.retaddr_on_stack = sigsave.retaddr; - set_process_mask (sigsave.oldmask); + sigsave.sig = 0; + if (sigsave.retaddr_on_stack) + { + *sigsave.retaddr_on_stack = sigsave.retaddr; + set_process_mask (sigsave.oldmask); + } } + sigproc_init (); } void __stdcall @@ -722,9 +736,9 @@ signal_fixup_after_exec (bool isspawn) /* Set up child's signal handlers */ for (int i = 0; i < NSIG; i++) { - myself->getsig(i).sa_mask = 0; - if (myself->getsig(i).sa_handler != SIG_IGN || isspawn) - myself->getsig(i).sa_handler = SIG_DFL; + myself->getsig (i).sa_mask = 0; + if (myself->getsig (i).sa_handler != SIG_IGN || isspawn) + myself->getsig (i).sa_handler = SIG_DFL; } } @@ -886,7 +900,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga) #error "Need to supply machine dependent setup_handler" #endif -/* CGF Keyboard interrupt handler. */ +/* Keyboard interrupt handler. */ static BOOL WINAPI ctrl_c_handler (DWORD type) { @@ -907,8 +921,18 @@ ctrl_c_handler (DWORD type) return FALSE; } + /* If we are a stub and the new process has a pinfo structure, let it + handle this signal. */ + if (dwExeced && pinfo (dwExeced)) + return TRUE; + + /* We're only the process group leader when we have a valid pinfo structure. + If we don't have one, then the parent "stub" will handle the signal. */ + if (!pinfo (cygwin_pid (GetCurrentProcessId ()))) + return TRUE; + tty_min *t = cygwin_shared->tty.get_tty (myself->ctty); - /* Ignore this if we're not the process group lead since it should be handled + /* Ignore this if we're not the process group leader since it should be handled *by* the process group leader. */ if (myself->ctty != -1 && t->getpgid () == myself->pid && (GetTickCount () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP) @@ -921,6 +945,7 @@ ctrl_c_handler (DWORD type) t->last_ctrl_c = GetTickCount (); return TRUE; } + return TRUE; } @@ -945,7 +970,7 @@ set_process_mask (sigset_t newmask) } int __stdcall -sig_handle (int sig) +sig_handle (int sig, bool thisproc) { int rc = 0; @@ -969,6 +994,7 @@ sig_handle (int sig) /* FIXME: Should we still do this if SIGCONT has a handler? */ if (sig == SIGCONT) { + DWORD stopped = myself->process_state & PID_STOPPED; myself->stopsig = 0; myself->process_state &= ~PID_STOPPED; /* Clear pending stop signals */ @@ -976,10 +1002,8 @@ sig_handle (int sig) sig_clear (SIGTSTP); sig_clear (SIGTTIN); sig_clear (SIGTTOU); - /* Windows 95 hangs on resuming non-suspended thread */ - SuspendThread (hMainThread); - while (ResumeThread (hMainThread) > 1) - ; + if (stopped) + SetEvent (sigCONT); /* process pending signals */ sig_dispatch_pending (1); } @@ -992,7 +1016,8 @@ sig_handle (int sig) if (handler == (void *) SIG_DFL) { - if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH) + if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH + || sig == SIGURG || (thisproc && hExeced && sig == SIGINT)) { sigproc_printf ("default signal %d ignored", sig); goto done; @@ -1013,9 +1038,6 @@ sig_handle (int sig) if (handler == (void *) SIG_ERR) goto exit_sig; - if ((sig == SIGCHLD) && (thissig.sa_flags & SA_NOCLDSTOP)) - goto done; - goto dosig; stop: @@ -1055,8 +1077,6 @@ sig_handle (int sig) static void signal_exit (int rc) { - extern HANDLE hExeced; - rc = EXIT_SIGNAL | (rc << 8); if (exit_already++) myself->exit (rc); @@ -1065,6 +1085,7 @@ signal_exit (int rc) causes random, inexplicable hangs. So, instead, we set up the priority of this thread really high so that it should do its thing and then exit. */ (void) SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); + (void) SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE); /* Unlock any main thread mutos since we're executing with prejudice. */ muto *m; @@ -1095,7 +1116,7 @@ events_init (void) api_fatal ("can't create title mutex, %E"); ProtectHandle (title_mutex); - mask_sync = new_muto (FALSE, "mask_sync"); + new_muto (mask_sync); windows_system_directory[0] = '\0'; (void) GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2); char *end = strchr (windows_system_directory, '\0'); @@ -1203,14 +1224,14 @@ _sigdelayed0: \n\ pushl %%ecx \n\ pushl %%ebx \n\ pushl %%eax \n\ - pushl %7 # saved errno \n\ + pushl %6 # saved errno \n\ pushl %3 # oldmask \n\ pushl %4 # signal argument \n\ pushl $_sigreturn \n\ \n\ call _reset_signal_arrived@0 \n\ pushl %5 # signal number \n\ - pushl %8 # newmask \n\ + pushl %7 # newmask \n\ movl $0,%0 # zero the signal number as a \n\ # flag to the signal handler thread\n\ # that it is ok to set up sigsave\n\ @@ -1221,7 +1242,7 @@ _sigdelayed0: \n\ __no_sig_end: \n\ " : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno), "g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig), - "g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno), "g" (sigsave.newmask) + "g" (sigsave.func), "g" (sigsave.saved_errno), "g" (sigsave.newmask) ); } } |